减少静态资产的节点/表达请求中反映的XSS

时间:2015-10-09 22:24:18

标签: angularjs node.js security express content-security-policy

我已经针对我的节点(快速)/角度应用程序运行了笔测试工具(Burp),并且在尝试GET静态资产请求时特别确定了一个反映的XSS漏洞(显然漏洞不是找到用户与应用程序交互时发出的任何请求。

问题详情是:

  

将任意提供的URL参数的名称复制到   未包含在任何引用中的JavaScript表达式   分数。有效载荷41b68(a)184a9 = 1以a的名义提交   任意提供的URL参数。此输入未经修改地回应   在应用程序的响应中。

     

此行为表明可以注入JavaScript   命令到返回的文档中。试图找出一个   注入任意JavaScript的完全概念验证攻击但是   这不成功。您应该手动检查应用程序   行为并尝试识别任何异常输入验证或其他   可能存在的障碍。

通过将任意url参数传递给请求来测试漏洞,如下所示:

GET /images/?41b68(a)184a9=1

回应是:

HTTP/1.1 404 Not Found
X-Content-Security-Policy: connect-src 'self'; default-src 'self'; font-src 'self'; frame-src; img-src 'self' *.google-analytics.com; media-src; object-src; script-src 'self' 'unsafe-eval' *.google-analytics.com; style-src 'self' 'unsafe-inline'
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
X-Download-Options: noopen
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 52
Date: Wed, 08 Oct 2015 10:46:43 GMT
Connection: close

Cannot GET /images/?41b68(a)184a9=1

您可以看到我有CSP(使用Helmet实现)和其他针对漏洞的保护。该应用程序通过https提供,但不需要用户身份验证。 CSP仅限应用于应用程序域的请求以及Google Analytics。

笔测试报告建议验证输入(我是,但是肯定会使请求包括用户发送的数据不安全,如果我不是吗?),并且编码html默认情况下有角度。

我真的很难找到针对这些静态资产请求阻止或减轻此问题的解决方案:

  • 我应该在csp下将我的申请的所有请求列入白名单吗?
  • 我甚至可以这样做,还是只将域名列入白名单?
  • 可以/应该以某种方式对node / express对静态资产请求的所有响应进行编码吗?
  • 报告指出"任意提供的URL参数的名称被复制到JavaScript表达式中,该表达式未封装在任何引号中"。这个表达式可能位于处理返回静态资产的快速代码中吗?
  • 或者可以在我的应用程序代码中以某种方式评估GET请求参数?

更新

对此进行了一些调查后,似乎至少部分缓解是escape data in url param valuessanitize the input in the url

网址的转义已经存在,所以:

curl 'http://mydomain/images/?<script>alert('hello')</script>'

返回

Cannot GET /images/?&lt;script&gt;alert(hello)&lt;/script&gt;

我还在此基础上设置了express-sanitized

但是,如果我卷曲原始测试,请求参数仍然会被反射回来。

curl 'http://mydomain/images/?41b68(a)184a9=1'
Cannot GET /images/?41b68(a)184a9=1

您期望的是因为html没有插入到网址中。

对静态资产的GET请求的响应全部由app.use(express.static('static-dir'))处理,因此查询将传递给此。 express.static基于serve-static,取决于parseurl

1 个答案:

答案 0 :(得分:0)

问题的原因是对于无效的GET请求,express将返回类似于:

的内容
Cannot GET /pathname/?yourQueryString

在许多情况下,即使对于提供静态资产,它也是有效的响应。但是,在我的情况下,我确信其他人对静态资产的唯一有效请求将是:

GET /pathname/your-file.jpg

我有一个返回数据对象的自定义404处理程序:

var data = {
    status: 404,
    message: 'Not Found',
    description: description,
    url: req.url
}; 

这仅针对app.js中的无效模板请求进行处理:

app.use('/template-path/*', function(req, res, next) {
    custom404.send404(req, res);
});

我现在为静态文件夹的请求添加了显式处理程序:

app.use('/static-path/*', function(req, res, next) {
        custom404.send404(req, res);
});

我可以选择在返回404之前删除请求查询参数:

var data = {
    status: 404,
    message: 'Not Found',
    description: description,
    url: url.parse(req.url).pathname // needs a var url = require('url')
};