【发布时间】:2011-08-14 21:15:31
【问题描述】:
因为使用 Origin / X-Frame-Options http 标头并不是很流行,而且我认为 Firefox 中的新 CSP 不会更好(开销、复杂等)我想提出一个建议一个新的 JavaScript / ECMA 版本。
但首先我发布这个想法,这样你就可以说它是否不好。我称之为简单jsPolicy:
每个使用 JavaScript 的人都在他的 html 头中放置了脚本。那么我们为什么不使用它们在那里添加我们的策略来控制所有后续脚本。示例:
<html>
<head>
<title>Example</title>
<script>
window.policy.inner = ["\nfunction foo(bar) {\n return bar;\n}\n", "foo(this);"];
</script>
</head>
<body>
<script>
function foo(bar) {
return bar;
}
</script>
<a href="#" onclick="foo(this);">Click Me</a>
<script>
alert('XSS');
</script>
</body>
</html>
现在浏览器将
当然,将所有内联代码加倍是没有用的,因此我们使用校验和。示例:
crc32("\nfunction foo(bar) {\n return bar;\n}\n");
结果“1077388790”
现在是完整的例子:
if (typeof window.policy != 'undefined') {
window.policy.inner = ["1077388790", "2501246156"];
window.policy.url = ["http://code.jquery.com/jquery*.js","http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"];
window.policy.relative = ["js/*.js"];
window.policy.report = ["api/xssreport.php"];
}
浏览器只需要比较内联脚本的校验和是否在policy.inner中设置,或者script.src URL是否适合policy.url。
注意:policy.relative 背后的想法是只允许本地脚本:
window.policy.url = false;
window.policy.relative = ["js/*.js"];
注意:policy.report 应该与使用 CSP 完成的几乎相同(将被阻止的脚本和 url 发送到 api):
https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-unofficial-draft-20110315.html#violation-report-syntax
重要:
- 政策不能设置两次(否则会引发警告)= 常量
- 考虑一下:策略只能设置在头部(否则会引发警告)
- 该策略仅用于检查作为 html 源的一部分的脚本,而不是那些即时放置的脚本。例子:
document.write('
您不需要为“http://code.jquery.com...”定义 policy.url,因为 policy.inner 校验和验证了完整的脚本源。这意味着即使 policy.url 设置为 false 也会加载源(是的,它仍然是安全的!)。这保证了该策略的简单用法。 - 如果缺少其中一项策略,则没有限制。这意味着一个空的 policy.relative 导致所有本地文件都被允许。这保证了向后兼容性
- 如果其中一个策略设置为“false”,则不允许使用(默认为 true)。例子:
policy.inner = false;
这不允许任何内联脚本 - 该策略仅忽略不允许的脚本并向控制台发出警告(错误会停止执行允许的脚本,这不是必需的)
我认为这将使 XSS 成为不可能,而不是 CSP,它还可以避免持久性 XSS(只要没有人覆盖策略)并且更新起来会容易得多。
你怎么看?
编辑:
这是一个用 Javascript 制作的示例:
http://www.programmierer-forum.de/php/js-policy-against-xss.php
当然我们无法控制脚本的执行,但它显示了如果 jsPolicy 兼容的浏览器可以控制它是如何工作的。
EDIT2:
不要以为我在谈论编写一个小 javascript 函数来检测 xss!我的 jsPolicy 想法必须是新 JavaScript 引擎的一部分。您可以将其与放置在 .htaccess 文件中的 php 设置进行比较。您不能在运行时更改此设置。同样的要求也适用于 jsPolicy。你可以称它为global setting。
jsPolicy 简而言之:
HTML 解析器 -> 将脚本发送到 JavaScript 引擎 -> 与 jsPolicy 比较 -> 是否允许?
A) 是的,通过 JavaScript 引擎执行
B) 不,忽略并将报告发送给网站管理员
EDIT3:
引用 Mike's comment 这也是一个可能的设置:
window.policy.eval = false;
【问题讨论】:
-
是的。如果这将成为新 Javascript / ECMA 版本的一部分,它将解决所有 XSS 问题。可能我解释得不好。你不清楚哪一部分?
-
我更新了解释并添加了更多示例。我希望现在更清楚了。
-
来自 MDC:“注意:出于安全原因,您不能使用 元素来配置 X-Content-Security-Policy 标头。”那是个很好的观点。您不能在客户端设置安全参数...如何安全?
-
@Rudie 我的想法是(如果浏览器符合策略要求),因为浏览器根据策略控制所有脚本执行。你知道为什么不允许 CSP 元数据吗?我认为这是因为您可以使用 JavaScript 覆盖元数据,并且忽略元数据比为不允许访问元数据的 javascript 引擎构建安全规则更容易。但我的想法没有可比的弱点,因为政策设置是不变的。
-
但是在 HTTP 标头中设置策略至少同样安全,您不同意吗?我认为更安全。而且只有几个字节。可能比 cookie 还少(现在那些效率低下)。 edit 也比你建议发送每个请求的 JS 少。所有解决方案都有“开销”。
标签: javascript html security xss same-origin-policy