【问题标题】:Mitigating reflected XSS in node/express requests for static assets缓解节点/快速静态资产请求中的反射 XSS
【发布时间】:2015-10-09 22:24:17
【问题描述】:

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

问题详情是:

将任意提供的 URL 参数的名称复制到 未封装在任何引用中的 JavaScript 表达式 分数。有效载荷 41b68(a)184a9=1 以 任意提供的 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 将请求限制为仅对应用程序的域加上谷歌分析。

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

对于那些对静态资产的请求,我真的很难找到一种解决方案来防止或减轻这种情况:

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

更新

对此进行了一些调查,似乎至少有一部分缓解措施是针对escape data in url param valuessanitize the input in the 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 基于 serve-static,而 parseurl 又依赖于 parseurl

【问题讨论】:

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


    【解决方案1】:

    问题的原因是对于无效的GET 请求,快递将返回如下内容:

    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')
    };
    

    【讨论】:

      猜你喜欢
      • 2020-03-27
      • 2017-09-07
      • 1970-01-01
      • 2012-09-02
      • 2023-03-26
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      相关资源
      最近更新 更多