Is it possible to tell browsers to not run JavaScript from specific parts of an HTML document?
Like:
<div script="false"> ...
It could be useful as an additional security feature. All the scripts I want are loaded in a specific part of the document. There should be no scripts in other parts of the document and if there are they should not be run.
javascript
html
script-tag
Seppo Erviälä
источник
источник
script-src:"self"
you allow only scripts from your domain to run in the page. If you are interested, read this article from Mike West about CSP.</div>
to close this DOM element and then starting a new<div>
that will be a sibling of the one where scripts aren't running?Ответы:
ДА, вы можете :-) Ответ: Политика безопасности контента (CSP).
Большинство современных браузеров поддерживают этот флаг , который указывает браузеру загружать только код JavaScript из надежного внешнего файла и запрещает весь внутренний код JavaScript! Единственным недостатком является то, что вы не можете использовать какой-либо встроенный JavaScript на всей странице (не только для одной
<div>
). Хотя может быть обходной путь путем динамического включения div из внешнего файла с другой политикой безопасности, но я не уверен в этом.But if you can change your site to load all JavaScript from external JavaScript files then you can disable inline JavaScript altogether with this header!
Here is a nice tutorial with example: HTML5Rocks Tutorial
If you can configure the server to send this HTTP-Header flag the world will be a better place!
источник
Вы можете заблокировать загрузку 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>
Обратите внимание, что это
beforescriptexecute
было определено в HTML 5.0, но было удалено в HTML 5.1. Firefox - единственный крупный браузер, в котором это реализовано.В случае, если вы вставляете ненадежную группу HTML на свою страницу, имейте в виду, что блокирующие скрипты внутри этого элемента не обеспечат большей безопасности, потому что ненадежный HTML может закрыть изолированный элемент, и, таким образом, скрипт будет размещен снаружи и запущен.
И это не заблокирует такие вещи, как
<img onerror="javascript:alert('foo')" src="//" />
.источник
beforescriptexecute
событие. Он работает в Firefox.beforescriptexecute
похоже, что он не поддерживается и не будет поддерживаться большинством основных браузеров. developer.mozilla.org/en-US/docs/Web/Events/beforescriptexecuteИнтересный вопрос, не думаю, что это возможно. Но даже если это так, похоже, что это взлом.
Если содержимое этого div не является доверенным, вам необходимо избежать данных на стороне сервера, прежде чем они будут отправлены в ответе HTTP и отображены в браузере.
Если вы хотите только удалить
<script>
теги и разрешить другие теги HTML, просто удалите их из содержимого и оставьте все остальное.Изучите предотвращение XSS.
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
источник
JavaScript выполняется «inline», то есть в том порядке, в котором он появляется в DOM (если бы это было не так, вы никогда не могли быть уверены, что какая-то переменная, определенная в другом скрипте, была видна, когда вы использовали ее в первый раз. ).
Теоретически это означает, что у вас может быть сценарий в начале страницы (т.е. первый
<script>
элемент), который просматривает DOM и удаляет все<script>
элементы и обработчики событий внутри вашего<div>
.Но в реальности все сложнее: загрузка DOM и скрипта происходит асинхронно. Это означает, что браузер гарантирует только то, что сценарий может видеть часть DOM, которая находится перед ним (то есть заголовок в нашем примере). Нет никаких гарантий ни на что сверх (это связано с
document.write()
). Так что вы можете увидеть следующий тег скрипта, а может быть, и нет.Вы могли
onload
зафиксировать событие документа - что обеспечило бы получение всей DOM - но в то время вредоносный код мог уже выполняться. Ситуация ухудшается, когда другие сценарии манипулируют DOM, добавляя туда сценарии. Таким образом, вам также придется проверять каждое изменение DOM.Итак, решение @cowls (фильтрация на сервере) - единственное решение, которое можно заставить работать во всех ситуациях.
источник
Если вы хотите отображать код JavaScript в своем браузере:
Используя JavaScript и HTML, вам придется использовать сущности HTML для отображения кода JavaScript и избегать выполнения этого кода. Здесь вы можете найти список объектов HTML:
Если вы используете язык сценариев на стороне сервера (PHP, ASP.NET и т. Д.), Скорее всего, есть функция, которая экранирует строку и преобразует специальные символы в объекты HTML. В PHP вы должны использовать «htmlspecialchars ()» или «htmlentities ()». Последний охватывает все символы HTML.
Если вы хотите красиво отобразить свой код JavaScript, попробуйте один из маркеров кода:
источник
У меня есть теория:
noscript
тег.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>
источник
<noscript>
бирку, а затем ввести то, что им нравится.Если вы захотите позже снова включить теги скриптов, я решил сломать среду браузера, чтобы любой запускаемый скрипт довольно рано выдавал ошибку. Однако он не совсем надежен, поэтому вы не можете использовать его в качестве средства безопасности.
Если вы попытаетесь получить доступ к глобальным свойствам, 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) {} } } }
источник