这是对抗 XSS 的好主意吗?
因为使用 Origin / X-Frame-Options http header 并不流行,而且我不认为 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('
- 如果其中一项政策缺失,则不受限制。这意味着空的policy.relative 会导致允许所有本地文件。这保证了向后兼容性,
- 如果其中一项策略设置为“false”,则不允许使用(默认为 true)。例子:
policy.inner = false;
这不允许任何内联脚本 - 该策略仅忽略不允许的脚本并向控制台发出警告(错误将停止允许的脚本的执行,这是不需要的)
我认为这将使 XSS 不可能,而不是 CSP 它也可以避免持久的 XSS(如长期以来没有人覆盖策略)并且更新会更容易。
你怎么认为?
编辑:
这是一个用 Javascript 编写的示例:
http://www.programmierer-forum.de/php/ js-policy-against-xss.php
当然,我们无法控制脚本的执行,但它显示了如果 jsPolicy 兼容的浏览器可以控制脚本的执行情况,它会如何工作。
编辑2:
不要以为我在谈论编写一些 javascript 函数来检测 xss!我的 jsPolicy 想法必须成为新 JavaScript 引擎的一部分。您可以将其与放入 .htaccess 文件中的 php 设置进行比较。您无法在运行时更改此设置。相同的要求也适用于 jsPolicy。您可以将其称为全局设置
。
jsPolicy 简而言之:
HTML 解析器 ->将脚本发送到 JavaScript 引擎 ->与 jsPolicy 比较 ->允许吗?
A) 是的,通过 JavaScript 引擎执行
B) 否,忽略并向网站管理员发送报告
EDIT3:
参考迈克的评论,这将是也可能的设置:
window.policy.eval = false;
as it isn't really popular to use Origin / X-Frame-Options http header and I don't think the new CSP in Firefox would be better (overhead, complicate, etc.) I want to make a proposal for a new JavaScript / ECMA version.
But first I publish the idea so you can say if its bad. I call it simple jsPolicy:
Everyone who uses JavaScript has placed scripts in his html head. So why don't we use them to add our policies there to control all following scripts. example:
<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>
Now the browser compares the <scripts>.innerHTML and the onclick.value with the ones in the policy and so the last script element block is not executed (ignored).
Of course it won't be useful to double all the inline code, so we use checksums instead. example:
crc32("\nfunction foo(bar) {\n return bar;\n}\n");
results "1077388790"
And now the full example:
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"];
}
The browser only needs to compare if the checksum of an inline script is set in the policy.inner or if the script.src URL fits to the policy.url.
Note: The idea behind policy.relative is to allow local scripts only:
window.policy.url = false;
window.policy.relative = ["js/*.js"];
Note: policy.report should be nearly the same as done with CSP (sends blocked scripts and urls to an api):
https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-unofficial-draft-20110315.html#violation-report-syntax
Important:
- The policy can't be set twice (else it throws a warning) = constant
- To think about: The policy can only be set in the head (else it throws a warning)
- The policy is only used to check the scripts that are part of the html source and not those that are placed on-the-fly. example:
document.write('<script src="http://code.jquery.com/jquery-1.5.2.min.js"></scr' + 'ipt>');
You don't need a policy.url definition for "http://code.jquery.com..." as the policy.inner checksum validated the complete script source. This means the source is loaded even if policy.url is set to false (yes it's still secure!). This garantuees a simple usage of the policy.
- if one of the policies is missing there is no limitation. This means that an empty policy.relative results that all local files are allowed. This guarantees backward compatibility
- if one of the policies is set to "false" no usage is allowed (default is true). example:
policy.inner = false;
This disallows any inline scripting
- The policy only ignores disallowed scripts and throws a warning to the console (an error would stop the execution of allowed scripts and this isn't needed)
I think this would make XSS impossible and instead of CSP it would avoid persistent XSS as well (as long nobody overwrites the Policy) and it would be much easier to update.
What do you think?
EDIT:
Here is an example made in Javascript:
http://www.programmierer-forum.de/php/js-policy-against-xss.php
Of course we can't control the script execution, but it shows how it could work if a jsPolicy compatible browser would.
EDIT2:
Don't think I'm talking about coding a little javascript function to detect xss!! My jsPolicy idea has to be part of a new JavaScript engine. You can compare it to a php-setting placed into the .htaccess file. You can not change this setting in runtime. The same requirements apply to jsPolicy. You can call it a global setting
.
jsPolicy in short words:
HTML parser -> send scripts to JavaScript Engine -> compare with jsPolicy -> is allowed?
A) yes, execution through JavaScript Engine
B) no, ignored and send report to webmaster
EDIT3:
Referenced to Mike's comment this would be a possible setting, too:
window.policy.eval = false;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
跨站点脚本编写发生在客户端。您的策略是在客户端定义的。看到问题了吗?
我喜欢内容安全策略,并且在我的所有项目中都使用它。事实上,我正在开发一个 JavaScript 框架,它的要求之一是“对 CSP 友好”。
光热发电> crossdomain.xml >你的政策。
Cross-site scripting occurs on the client-side. Your policies are defined on the client-side. See the problem?
I like Content Security Policy, and I use it on all of my projects. In fact, I am working on a JavaScript framework, which has one of its requirements "be CSP-friendly."
CSP > crossdomain.xml > your policy.
绝大多数 XSS 攻击来自“可信”来源,至少就浏览器而言是这样。它们通常是回显用户输入的结果,例如在论坛中,并且没有正确转义输入。您永远不会因为链接到 jquery 而遭受 XSS,而且从任何其他链接源中获得 XSS 的情况也是极其的罕见情况。
如果您尝试执行跨域脚本编写,则无法获取远程脚本的校验和。
所以虽然你的想法看起来不错,但我真的不认为它有什么意义。
The vast majority of XSS attacks come from "trusted" sources, at least as far as the browser is concerned. They are usually the result of echo'ing user input, e.g. in a forum, and not properly escaping the input. You're never going to get an XSS from linking to jquery, and it is extremely rare that you will from any other linked source.
In the case when you are trying to do cross-domain scripting, you can't get a checksum on the remote script.
So although your idea seems fine, I don't really see a point to it.
这个想法不断被提出并重新提出……每次安全专家都会揭穿它。
无意听起来刺耳,但这不是一个开发问题,而是一个安全问题。具体来说,大多数开发人员并没有意识到有多少变体、向量、漏洞利用和规避技术。
正如这里提到的其他一些答案,问题在于您的解决方案无法解决是否信任到达浏览器的任何内容的问题,因为在客户端您无法知道什么是代码,什么是代码是数据。即使您的解决方案也无法阻止这种情况。
例如,请参阅ITsec.SE 上的此问题,了解实现此功能的一些实际问题。
(你的问题或多或少与那个问题有点重复......)
顺便说一句,关于 CSP - 检查这个 其他问题ITsec.SE。
This idea keeps getting floated and re-floated every so often... and each time security experts debunk it.
Don't mean to sound harsh, but this is not a development problem, it is a security problem. Specifically, most developers don't realize how many variants, vectors, exploits and evasion techniques there are.
As some of the other answers here mentioned, the problem is that your solution does not solve the problem, of whether or not to trust whatever arrives at the browser, since on the client side you have no way of knowing what is code, and what is data. Even your solution does not prevent this.
See e.g. this question on ITsec.SE for some of the practical issues with implementing this.
(your question is kinda a duplicate of that one, more or less... )
Btw, re CSP - check this other question on ITsec.SE.
看起来你已经把整个游戏都泄露出去了。
如果我有类似的代码
,并且有人使用查询字符串
?eval=alert%28%22pwned%22%29
诱骗用户访问我的网站,那么他们就已被 XSS 攻击,而您的策略没有执行任何操作阻止它。It seems like you've given the whole game away here.
If I have code like
and someone tricks a user into visiting my site with the query string
?eval=alert%28%22pwned%22%29
then they've been XSSed, and your policy has done nothing to stop it.