Ответ 1
Код вопроса содержит общую проблему безопасности, известную как XSS. Поскольку вы берете ненадежный ввод и назначаете его .innerHTML
, вы разрешаете злоумышленникам вставлять произвольный HTML в контексте вашего документа.
К счастью, злоумышленники не могут запускать скрипты в контексте вашего расширения, потому что расширение по умолчанию Политика безопасности контента запрещает встроенные скрипты. Этот CSP применяется в расширениях Chrome именно из-за таких ситуаций, чтобы предотвратить уязвимости XSS.
Правильный способ преобразования HTML в текст осуществляется через DOMParser
API. Следующие две функции показывают, как копировать текст в виде текста, или для вашего случая HTML в виде текста:
// Copy text as text
function executeCopy(text) {
var input = document.createElement('textarea');
document.body.appendChild(input);
input.value = text;
input.focus();
input.select();
document.execCommand('Copy');
input.remove();
}
// Copy HTML as text (without HTML tags)
function executeCopy2(html) {
var doc = new DOMParser().parseFromString(html, 'text/html');
var text = doc.body.textContent;
return executeCopy(text);
}
Обратите внимание, что .textContent
полностью игнорирует теги HTML. Если вы хотите интерпретировать <br>
как разрывы строк, используйте нестандартное (но поддерживаемое в Chrome) свойство .innerText
вместо .textContent
.
Вот два из многих примеров того, как XSS можно злоупотреблять с помощью функции executeCopy
из вашего вопроса:
// This does not only copy "Text", but also trigger a network request
// to example.com!
executeCopy('<img src="http://example.com/">Text');
// If you step through with a debugger, this will show an "alert" dialog
// (an arbitrary script supplied by the attacker!!)
debugger;
executeCopy('<iframe src="data:text/html,<script>alert(/XXS-ed!/);<\/script>"></iframe>');