使用CSP防止自动点击链接XSS攻击

时间:2015-04-20 15:50:35

标签: javascript xss content-security-policy

虽然使用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之类的东西似乎存在,以防止信息泄露,即使在这些情况下也是如此。

3 个答案:

答案 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攻击;最好完全避免它们。

如果您认为有必要出于某种原因在文档中嵌入内容,那么可以在您的策略字符串中放置哈希值和现时值,以便将内联脚本列入白名单。