虽然使用CSP的目的略有不同(沙盒),但我意识到一个非常简单的自动点击链接似乎绕过了相对严格的CSP。我所描述的是以下内容:
内容安全政策:
default-src 'none'; script-src 'unsafe-inline';
身体:
<a href="http://www.google.com">test</a>
<script>
document.querySelector("a").click();
</script>
显然,在真正的攻击中,您首先会将Cookie信息包含在href
字段中,并可能将其包含在隐藏的自嵌入iframe中,或者让域重定向到您来自的位置(可能还有其他内容) url参数因此创建了一种绕过connect-src
)的XMLHttpRequest,但这个基本示例确实显示了问题。
有没有办法用CSP阻止这种情况(仍允许执行Javascript)?
显然,使用其他一些导航方法也可以做同样的事情。我之所以特别询问这种方法的原因实际上与我的次要目标有关,而不是XSS漏洞。无论哪种方式,都可以使用任何真正的解决方案。
由于所有的困惑,即使没有script-src: 'unsafe-inline'
,这仍然可以适用。想象一下名为api.ext
print URLParameters.method
[...]
然后可以像api.ext?method=<script src='api.ext?method=alert("test")//'></script><!--
一样调用此文件(除非您需要额外的URL编码和内容,这只是为了解决问题)。找到这样的漏洞是很难的,而且很少见,但connect-src
之类的东西似乎存在,以防止信息泄露,即使在这些情况下也是如此。
答案 0 :(得分:2)
这不太可能是令人满意的方法 - 显然它不是基于CSP - 但如果你真的必须防止此类攻击,它可能是你唯一的选择。在使用这样的东西之前,请确保没有办法禁用内联脚本(应该涵盖大多数攻击)。此外,您应该将您的反馈发送到带有[CSP2]主题的public-webappsec@w3.org邮件列表。
这是我的(不完整的)想法:
function guardMethods(clazz, methodNames, urlGetter, allowFilter, reportViolation) {
var prototype = clazz.prototype;
methodNames.forEach(function (methodName) {
var originalMethod = prototype[methodName];
if (originalMethod) {
Object.defineProperty(prototype, methodName, {
value: function () {
var url = urlGetter.apply(this, arguments) || '';
if (allowFilter(url)) {
return originalMethod.apply(this, arguments);
} else {
reportViolation(url);
}
}
});
}
})
}
function allowFilter(url) {
// todo: implement
}
function reportViolation(url) {
console.error('Redirection prevented:', url);
}
guardMethods(HTMLAnchorElement, ['click', 'dispatchEvent', 'fireEvent'], function () {return this.href}, allowFilter, reportViolation);
您必须为location,location.href,window.open和其他允许重定向到其他页面的函数/属性/事件实现类似的保护。如果你只想念一个,那么你仍然很脆弱。 CSP本身可以涵盖表单,XHR和大多数其他资源。据我所知,原型黑客在某些旧版浏览器中不起作用。
再一次,我不建议使用它。您在某些浏览器中出错或者无法添加可能用于重定向的新API的可能性太大。
答案 1 :(得分:0)
CSP是减少XSS造成的损害的方法之一,但它绝不是一个修复由XSS漏洞引起的所有问题的魔棒。此非目标也明确列在CSP specification:
中内容安全策略(CSP)不是针对内容注入漏洞的第一道防线。相反,CSP最好用作深度防御,以减少内容注入攻击造成的伤害。作为内容注入的第一道防线,服务器运营商应验证其输入并对其输出进行编码。
如果您必须运行JavaScript代码,但无法信任代码,那么您可以使用不带allow-same-origin
标志的沙盒指令来提供页面。使用此CSP指令,页面将以唯一的安全源运行,该源不与显示的源共享任何状态(即cookie,DOM存储,数据库......)。因此,注入的脚本不会泄漏信息,因为它们无法在第一时间获取信息。
例如,要允许内联脚本运行,但无法访问同源数据,请使用:
default-src 'none'; script-src 'unsafe-inline'; sandbox allow-scripts
不要像其他答案所建议的那样将黑名单列入JavaScript列表,因为1)您将始终忽略一种方法,2)禁用JavaScript API可能会以意想不到的方式破坏您的Web应用程序,以及3)攻击者只需要一个洞造成伤害,你的(自定义)应用程序可能包含至少一种可被攻击者滥用的方法。
答案 2 :(得分:-2)
内容安全策略是为了页面本身的安全性。导航到另一个页面不是旁路或涉及CSP的东西。 CSP只关注您的网页及其功能。它也不是为了限制最终用户的浏览器实用程序(比如安装插件或打开链接的能力)。
default-src 'none';
这使政策变得紧张,不允许任何地方出现XHR / Fetch / WebSockets / CSS / Font / JavaScript / Plugin内容。这些都具有各自的属性,但在缺少时使用默认属性。您没有尝试在javascript中执行任何操作。
script-src 'unsafe-inline';
这放宽了政策,允许使用嵌入页面的任何JavaScript。这包括onclick / onhover以及不安全属性的整个系列。引用spec:
在任何一种情况下,作者都不应该包括“不安全内联”或数据:作为其政策中的有效来源。两者都允许代码直接包含在文档本身中,从而实现XSS攻击;最好完全避免它们。
如果您认为有必要出于某种原因在文档中嵌入内容,那么可以在您的策略字符串中放置哈希值和现时值,以便将内联脚本列入白名单。