Могу ли я попросить браузер не запускать <script> s внутри элемента?

Можно ли сказать браузерам, чтобы они не запускали JavaScript из определенных частей документа HTML?

Как

<div script="false"> ...

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

Ответ 1

ДА, вы можете:-) Ответ: Политика безопасности контента (CSP).

Большинство современных браузеров поддерживают этот флаг, который сообщает браузеру только загружать код JavaScript из надежного внешнего файла и запрещать все внутренние JavaScript-коды! Единственным недостатком является то, что вы не можете использовать встроенный JavaScript на всей странице (не только для одного <div>). Хотя может быть временное решение, динамически включающее div из внешнего файла с другой политикой безопасности, но я не уверен в этом.

Но если вы можете изменить свой сайт для загрузки всего JavaScript из внешних файлов JavaScript, вы можете отключить встроенный JavaScript в целом с этим заголовком!

Вот хороший учебник с примером: Учебник HTML5Rocks

Если вы можете настроить сервер для отправки этого заголовка HTTP-заголовка, мир станет лучшим местом!

Ответ 2

Вы можете заблокировать JavaScript, загруженный <script>, используя beforescriptexecute событие:

<script>
  // Run this as early as possible, it isn't retroactive
  window.addEventListener('beforescriptexecute', function(e) {
    var el = e.target;
    while(el = el.parentElement)
      if(el.hasAttribute('data-no-js'))
        return e.preventDefault(); // Block script
  }, true);
</script>

<script>console.log('Allowed. Console is expected to show this');</script>
<div data-no-js>
  <script>console.log('Blocked. Console is expected to NOT show this');</script>
</div>

Ответ 3

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

Если содержимое этого div недостоверно, вам необходимо избежать данных на стороне сервера, прежде чем он будет отправлен в ответе HTTP и отображен в браузере.

Если вы хотите удалить теги <script> и разрешить другие теги html, просто отделите их от содержимого и оставьте остальные.

Посмотрите на предотвращение XSS.

https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

Ответ 4

JavaScript выполняется "inline", то есть в том порядке, в котором он отображается в DOM (если это не так, вы никогда не могли быть уверены, что какая-либо переменная, определенная в другом script, была видна, когда вы использовали это в первый раз).

Таким образом, теоретически вы можете иметь script в начале страницы (т.е. первый элемент <script>), который просматривает DOM и удаляет все элементы <script> и обработчики событий внутри вашего <div>.

Но реальность более сложная: загрузка DOM и script происходит асинхронно. Это означает, что браузер только гарантирует, что script может видеть часть DOM, которая находится перед ним (т.е. Заголовок до сих пор в нашем примере). Нет никаких гарантий для чего-либо (это связано с document.write()). Таким образом, вы можете увидеть следующий тег script или, может быть, вы этого не сделаете.

Вы можете защелкнуть событие onload документа, которое должно было удостовериться, что вы получили всю DOM, но в то время вредоносный код мог быть уже выполнен. Все хуже, когда другие скрипты манипулируют DOM, добавив там скрипты. Поэтому вам также нужно будет проверить все изменения DOM.

Таким образом, решение @cowls (фильтрация на сервере) является единственным решением, которое может быть сделано для работы во всех ситуациях.

Ответ 5

Если вы хотите отобразить код JavaScript в своем браузере:

Используя JavaScript и HTML, вы должны будете использовать HTML-сущности, чтобы отобразить код JavaScript и избежать выполнения этого кода. Здесь вы можете найти список объектов HTML:

Если вы используете серверный язык сценариев (PHP, ASP.NET и т.д.), то, скорее всего, есть функция, которая позволит избежать строки и преобразовать специальные символы в объекты HTML. В PHP вы должны использовать "htmlspecialchars()" или "htmlentities()". Последний охватывает все символы HTML.

Если вы хотите показать свой код JavaScript красивым способом, попробуйте один из элементов выделения кода:

Ответ 6

У меня есть теория:

  • Оберните определенную часть документа внутри тега noscript.
  • Используйте функции DOM, чтобы отбросить все теги script внутри тега noscript, а затем развернуть его содержимое.

Доказательство примера концепции:

window.onload = function() {
    var noscripts = /* _live_ list */ document.getElementsByTagName("noscript"),
        memorydiv = document.createElement("div"),
        scripts = /* _live_ list */ memorydiv.getElementsByTagName("script"),
        i,
        j;
    for (i = noscripts.length - 1; i >= 0; --i) {
        memorydiv.innerHTML = noscripts[i].textContent || noscripts[i].innerText;
        for (j = scripts.length - 1; j >= 0; --j) {
            memorydiv.removeChild(scripts[j]);
        }
        while (memorydiv.firstChild) {
            noscripts[i].parentNode.insertBefore(memorydiv.firstChild, noscripts[i]);
        }
        noscripts[i].parentNode.removeChild(noscripts[i]);
    }
};
body { font: medium/1.5 monospace; }
p, h1 { margin: 0; }
<h1>Sample Content</h1>
<p>1. This paragraph is embedded in HTML</p>
<script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script>
<p>3. This paragraph is embedded in HTML</p>
<h1>Sample Content in No-JavaScript Zone</h1>
<noscript>
    <p>1. This paragraph is embedded in HTML</p>
    <script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script>
    <p>3. This paragraph is embedded in HTML</p>
</noscript>
<noscript>
    <p>1. This paragraph is embedded in HTML</p>
    <script>document.write('<p style="color: red;">2. This paragraph is generated by JavaScript</p>');</script>
    <p>3. This paragraph is embedded in HTML</p>
</noscript>

Ответ 7

Если вы хотите снова включить теги script позже, мое решение состояло в том, чтобы разбить среду браузера, чтобы любой выполняемый script выдавал ошибку довольно рано. Однако он не является полностью надежным, поэтому вы не можете использовать его как функцию безопасности.

Если вы попытаетесь получить доступ к глобальным свойствам, Chrome сделает исключение.

setTimeout("Math.random()")
// => VM116:25 Uncaught Error: JavaScript Execution Inhibited  

Я перезаписываю все перезаписываемые свойства на window, но вы также можете развернуть его, чтобы нарушить другие функции.

window.allowJSExecution = inhibitJavaScriptExecution();
function inhibitJavaScriptExecution(){

    var windowProperties = {};
    var Object = window.Object
    var console = window.console
    var Error = window.Error

    function getPropertyDescriptor(object, propertyName){
        var descriptor = Object.getOwnPropertyDescriptor(object, propertyName);
        if (!descriptor) {
            return getPropertyDescriptor(Object.getPrototypeOf(object), propertyName);
        }
        return descriptor;
    }

    for (var propName in window){
        try {
            windowProperties[propName] = getPropertyDescriptor(window, propName)
            Object.defineProperty(window, propName, {
                get: function(){
                    throw Error("JavaScript Execution Inhibited")
                },
                set: function(){
                    throw Error("JavaScript Execution Inhibited")
                },
                configurable: true
            })
        } catch (err) {}
    }

    return function allowJSExecution(){
        for (var propName in window){
            if (!(propName in windowProperties)) {
                delete windowProperties[propName]
            }
        }

        for (var propName in windowProperties){
            try {
                Object.defineProperty(window, propName, windowProperties[propName])
            } catch (err) {}
        }
    }
}