我可以让浏览器不要在元素中运行<script>?

是否有可能告诉浏览器不要从HTML文档的特定部分运行JavaScript?

喜欢:

<div script="false"> ... 

这可能是一个额外的安全function。 我想要的所有脚本都被加载到文档的特定部分。 在文档的其他部分不应该有脚本,如果有的话不应该运行。

是的,你可以:-)答案是: 内容安全策略 (CSP)。

大多数现代浏览器都支持这个标志 ,它告诉浏览器只从一个可信的外部文件加载JavaScript代码,并禁止所有的JavaScript代码! 唯一的缺点是,你不能在整个页面中使用任何内联JavaScript(不仅仅是一个<div> )。 虽然可以有一个解决方法,dynamic地包含从不同的安全策略的外部文件的div,但我不知道这一点。

但是,如果您可以更改网站以从外部JavaScript文件加载所有JavaScript,那么您可以使用此标头完全禁用内联JavaScript!

这里是一个很好的教程,例如: HTML5Rocks教程

如果你可以configuration服务器发送这个HTTP-Header标志,那么这个世界将是一个更好的地方!

您可以使用beforescriptexecute事件阻止由<script>加载的JavaScript:

 <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> 

有趣的问题,我不认为这是可能的。 但即使是这样,这听起来像是一个黑客。

如果该div的内容是不可信的,那么在HTTP响应中发送并在浏览器中呈现之前,您需要在服务器端转义数据。

如果你只想删除<script>标签,并允许其他的html标签,那么就把它们从内容中删除,剩下的就放在那里。

研究XSS预防。

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

JavaScript是以“内联”的方式执行的,即按照它在DOM中出现的顺序执行(如果不是这样的话,那么当你第一次使用它时,你不能确定在不同脚本中定义的variables是可见的)。

所以这就意味着理论上你可以在页面的开始处有一个脚本(即第一个<script>元素),它通过DOM查看并删除你的<div>所有<script>元素和事件处理程序。

但现实是更复杂的:DOM和脚本加载发生asynchronous。 这意味着浏览器只能保证一个脚本能够看到它之前的那个DOM的部分(也就是我们例子中的头部)。 除了(这与document.write()有关document.write()之外没有任何保证。 所以你可能会看到下一个脚本标记,或者你可能看不到。

你可以locking到文档的onload事件 – 这将确保你得到了整个DOM – 但在那个时候,恶意代码可能已经执行。 当其他脚本处理DOM时,情况会变得更糟,在那里添加脚本。 所以你也必须检查DOM的每一个变化。

所以@cowls解决scheme(在服务器上过滤)是唯一可以在所有情况下工作的解决scheme。

如果您要在浏览器中显示JavaScript代码,请执行以下操作:

使用JavaScript和HTML,您将不得不使用HTML实体来显示JavaScript代码,并避免执行此代码。 在这里你可以findHTML实体列表:

如果您使用服务器端脚本语言(PHP,ASP.NET等),最有可能的是,有一个函数可以转义string并将特殊字符转换为HTML实体。 在PHP中,您可以使用“htmlspecialchars()”或“htmlentities()”。 后者涵盖了所有的HTML字符。

如果您希望以很好的方式显示您的JavaScript代码,请尝试使用其中一个代码荧光笔:

我有一个理论:

  • 将文档的特定部分封装在noscript标签中。
  • 使用DOM函数放弃noscript标签内的所有script标签,然后解开其内容。

概念例证的certificate:

 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> 

如果您稍后要重新启用脚本标记,我的解决scheme是打破浏览器环境,以便任何运行的脚本都会相当早地抛出错误。 但是,这不是完全可靠的,所以你不能把它用作安全function。

如果您尝试访问全球属性,Chrome会抛出exception。

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

我正在覆盖window上的所有可覆盖的属性,但你也可以扩展它来打破其他function。

 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) {} } } }