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

Sep*_*älä 82 html javascript script-tag

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

喜欢:

<div script="false"> ...
Run Code Online (Sandbox Code Playgroud)

它可以作为一个额外的安全功能.我想要的所有脚本都加载到文档的特定部分.文档的其他部分应该没有脚本,如果不存在则不应该运行.

Fal*_*lco 91

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

大多数现代浏览器都支持此标志,该标志仅告知浏览器从可信外部文件加载JavaScript代码并禁止所有内部JavaScript代码!唯一的缺点是,您不能在整个页面中使用任何内联JavaScript(不仅仅是单个<div>).虽然可以通过动态包含来自具有不同安全策略的外部文件的div来解决此问题,但我不确定.

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

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

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

  • 请注意,即使您这样做,在页面上允许未转义的用户输入仍然是一个坏主意.这基本上允许用户将页面更改为他们想要的外观.即使将所有内容安全策略(CSP)设置设置为最大值(禁止内联脚本,样式等),用户仍然可以使用映像srcs对GET请求执行跨站点请求伪造(CSRF)攻击,或欺骗用户单击POST请求的表单提交按钮. (4认同)
  • @Falco是的,这基本上是StackExchange对新的Stack Snippets功能所做的:http://blog.stackoverflow.com/2014/09/introducing-runnable-javascript-css-and-html-code-snippets/如果你正确消毒虽然输入,但没有必要使用单独的域. (3认同)
  • +1这真的很酷,我不知道存在!(请注意,您的wiki链接是直接使用德语版本)以下是浏览器支持的概述:http://caniuse.com/#feat=contentsecuritypolicy (2认同)

Ori*_*iol 13

您可以<script>使用beforescriptexecute事件阻止加载的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>
Run Code Online (Sandbox Code Playgroud)

请注意,它beforescriptexecute是在HTML 5.0中定义的,但已在HTML 5.1中删除.Firefox是唯一实现它的主要浏览器.

如果您在页面中插入不受信任的HTML,请注意该元素中的阻塞脚本不会提供更多安全性,因为不受信任的HTML可以关闭沙盒元素,因此脚本将放在外面并运行.

这不会阻止像这样的事情<img onerror="javascript:alert('foo')" src="//" />.


cow*_*wls 8

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

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

如果您只想删除<script>标签并允许其他html标签,那么只需将它们从内容中删除即可.

研究XSS预防.

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


Aar*_*lla 7

JavaScript以"内联"的形式执行,即按照它在DOM中出现的顺序执行(如果不是这种情况,则在第一次使用时,您永远无法确定在不同脚本中定义的某些变量是否可见).

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

但实际情况更复杂:DOM和脚本加载是异步发生的.这意味着浏览器只保证脚本可以看到它之前的DOM部分(即我们示例中的标题).除了(与此相关document.write())之外,没有任何保证.所以你可能会看到下一个脚本标签,或者你可能看不到.

您可以锁定onload文档的事件 - 这将确保您获得整个DOM - 但那时,恶意代码可能已经执行.当其他脚本操纵DOM,在那里添加脚本时,情况变得更糟.因此,您还必须检查DOM的每个更改.

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