是否可以告诉浏览器不要从HTML文档的特定部分运行JavaScript?
喜欢:
<div script="false"> ...
它可能作为附加的安全功能很有用。我想要的所有脚本均已加载到文档的特定部分。文档其他部分中不应包含脚本,如果存在,则不应运行它们。
是否可以告诉浏览器不要从HTML文档的特定部分运行JavaScript?
喜欢:
<div script="false"> ...
它可能作为附加的安全功能很有用。我想要的所有脚本均已加载到文档的特定部分。文档其他部分中不应包含脚本,如果存在,则不应运行它们。
script-src:"self"
您只允许您域中的脚本在页面中运行。如果您有兴趣,请阅读Mike West撰写的有关CSP的文章。
</div>
来关闭此DOM元素,然后启动一个新的<div>
将不运行脚本的同级兄弟?
Answers:
是的,您可以:-)答案是:内容安全策略(CSP)。
大多数现代浏览器都支持此标志,该标志告诉浏览器仅从受信任的外部文件中加载JavaScript代码,并禁止所有内部JavaScript代码!唯一的缺点是,您不能在整个页面中使用任何内联JavaScript(不仅限于单个<div>
)。尽管可以通过动态地将具有不同安全策略的外部文件中的div包括在内来解决,但我不确定。
但是,如果您可以更改站点以从外部JavaScript文件加载所有JavaScript,则可以与此标头一起完全禁用嵌入式JavaScript!
这是一个带有示例的不错的教程:HTML5Rocks教程
如果您可以将服务器配置为发送此HTTP-Header标志,那么世界将是一个更好的地方!
您可以<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>
请注意,它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是“内联”执行的,即按照它在DOM中出现的顺序执行(如果不是这样,您将无法确定第一次使用该脚本时在其他脚本中定义的某些变量是可见的) )。
因此,从理论上讲,这意味着您可以在页面开始处有一个脚本(即第一个<script>
元素),该脚本可以查看DOM并删除其中的所有<script>
元素和事件处理程序<div>
。
但是实际情况更为复杂:DOM和脚本加载是异步发生的。这意味着浏览器仅保证脚本可以看到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) {}
}
}
}