Используйте window.open, но блокируйте использование window.opener

A назад я встретил интересную дыру в безопасности

<a href="#" onclick="location.href='http://someurl.here'; return false;" target="_blank">Link</a>

Выглядит достаточно безобидно, но есть дыра, потому что по умолчанию открываемая страница позволяет открытой странице перезвонить ей через window.opener. Существуют некоторые ограничения, являющиеся междоменными, но все же есть некоторые оскорбления, которые можно сделать

window.opener.location = 'http://gotcha.badstuff';

Теперь HTML имеет обходное решение

<a href="#" onclick="location.href='http://someurl.here'; return false;" target="_blank" rel="noopener noreferrer">Link</a>

Это предотвращает передачу нового окна window.opener. Это хорошо и хорошо для HTML, но что, если вы используете window.open?

<button type="button" onclick="window.open('http://someurl.here', '_blank');">
    Click Me
</button>

Как вы можете заблокировать использование window.opener здесь?

Ответ 1

использование

var yourWindow = window.open();
yourWindow.opener = null;
yourWindow.location = "http://someurl.here";

Кредит идет к Матиасу Биненсу: https://mathiasbynens.github.io/rel-noopener/

Ответ 2

Вызов window.open() теперь поддерживает функцию "noopener".
Поэтому вызов window.open('https://www.your.url','_blank','noopener') должен открыть новое окно/вкладку с нулевым window.opener.

У меня проблемы с поиском надежного списка поддерживаемых браузеров (и версий) - здесь MDN заявляет, что

Это поддерживается в современных браузерах, включая Chrome и Firefox 52+.

Из моих экспериментов я вижу, что это работает для:

  • Chrome 61
  • FireFox 56
  • Safari 11.1 (спасибо Цзяи Ху за это)

Но не работает для:

  • IE 11.608
  • Край 40

(Все тесты на ПК под управлением Windows 10...)

Для обратной совместимости может быть лучше объединить это с ответом t3__rry.

Ответ 3

Это сработало для меня:

const a = document.createElement("a")
a.href = args.url
a.target = "_blank"
a.rel = "noopener"
a.click()

Ответ 5

После того, как браузеры добавят поддержку директивы CSP disown-opener, вы сможете просто использовать это:

<meta http-equiv="Content-Security-Policy" content="disown-opener">

Или как заголовок HTTP:

Content-Security-Policy: disown-opener

В любом случае эффект заключается в установке window.opener в null для любых новых окон, которые создаются из документа, который включает в себя эту директиву CSP.

Но disown-opener является недавним дополнением к CSP, и насколько я знаю, браузеры еще не поддерживают его.