减轻节点/express对静态资产的请求中反映的XSS



我对我的节点(express)/angular应用程序运行了一个渗透测试工具(Burp),它识别了一个反映的XSS漏洞,特别是在尝试静态资产的GET请求时(显然,当用户与应用程序交互时,没有发现任何请求的漏洞)。

问题详情如下:

任意提供的URL参数的名称被复制到JavaScript表达式,没有封装在任何引号中马克。有效载荷41b68(a)184a9=1以an的名义提交任意提供的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到位(使用头盔实现)和其他保护针对漏洞利用。该应用程序通过https提供,但不需要用户授权。CSP限制请求的应用程序的域名只加上谷歌分析。

渗透测试报告建议验证输入(我是,但如果我不是,肯定会使请求包括用户发送的数据不安全?),并编码html, angular默认是这样做的。

我真的很难找到一个解决方案来防止或减轻这些请求的静态资产:

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

更新

在对此进行了一些调查之后,似乎至少有一部分缓解措施是转义url参数值中的数据并对url中的输入进行消毒。

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没有插入到url中。

对静态资产GET请求的响应都由app.use(express.static('static-dir'))处理,因此查询被传递到此。

express.static是基于service -static的,依赖于parseurl。

问题的原因是对于无效的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')
};

最新更新