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

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

<a href="http://someurl.here" target="_blank">Link</a>

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

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

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

<a href="http://someurl.here" 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 передается здесь?

6 ответов

Решение

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

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

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

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

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

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

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

  • Chrome 61
  • FireFox 56
  • Safari 11.1 (спасибо Jiayi Hu за это)

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

  • IE 11.608
  • Край 40

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

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

Указывая, что это список функций, разделенных запятыми (без пробелов), поэтому вы можете установить 'noopener,noreferrer,resizable' то есть:

      window.open('http://sensible.url', '_blank', 'noopener,noreferrer,resizable')

Из документов Mozilla :

windowFeatures Необязательный

Строка DOMString, содержащая разделенный запятыми список функций окна с соответствующими значениями в форме «имя = значение». [...]

Согласно документации ( https://developer.mozilla.org/en/docs/Web/API/Window/open), в следующем коде

window.open('https://www.your.url','_blank','noopener')

Третий аргумент содержит "WindowFeatures" (см. https://developer.mozilla.org/en-US/docs/Web/API/Window/open), поэтому имеет смысл открыть цель в новом окне.

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

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

ОБНОВИТЬ: target="_blank" подразумевая rel="noopener"поведение было предложено в #4078 и исправлено в PR#4330 от 31.01.2019

Большинство современных браузеров включили это изменение, но в основном это новейшие версии. Источник: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#browser_compatibility.

Другие вопросы по тегам