XXE与CSHM防范

安全反馈了我们系统存在的一些问题
虽然不是我的代码导致,但还是趁机学习了一下

主要是 “XML实体引用约束不足”“跨站历史操作”

XXE

XML External Entity

原因是咱用了鹅厂某个变更回调的接口,而这个回调的数据是XML格式的(为什么不是JSON?
于是代码中简单得使用了DocumentBuilder的parse方法来解析XML,导致了安全问题

XML

Extensible Markup Language,提供了一种标准的、可扩展的数据交换格式
DTD(文档类型定义)是用来定义 XML 文档的合法构建模块
DTD有两种使用方式:

  • 内部DTD:即DTD的声明和属性都在 XML 中
  • 外部DTD:即 XML 中使用的 DTD 引用了一个外部的单独的DTD文件

为什么

  1. XML组件默认没有禁用外部实体引用,XML 实体可动态包含来自给定资源的数据。
  2. XML 解析器无法预防和限制外部实体进行解析,这会使解析器暴露在 XML External Entities 攻击之下。
  3. 当动态构建XML时,XML 解析器可以访问由用户输入的 URI 所指定的资源,因此可能导致读取任意文件;执行系统命令;探测内网端口;攻击内网网站等

因此外界攻击者可以通过模拟回调通知,在回调通知中引入不安全的XML来达到自己的目的

解决办法

事实上,当前的SpringBoot版本已经修复了这个漏洞,但如果使用更早期的版本或其他框架,可能遭受风险。

所以,咱们需要做的就是禁用DTD以及外部实体引用

  1. JAVA

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 完全禁用DTD
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

    // 不包括外部一般实体
    dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
    // 不包含外部参数实体或外部DTD
    dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    // 忽略外部DTD
    dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    dbf.setExpandEntityReferences(false);

    最好再加上 异常捕获 ,以免一些意外发生

  2. PHP

    1
    2
    libxml_disable_entity_loader(true);
    $xml = simplexml_load_string($xmlContent);
  3. Python

    1
    2
    from lxml import etree
    xmlData = etree.parse(xmlContent,etree.XMLParser(resolve_entities=False))

跨站历史操作

Cross Site History Manipulation

为什么

现代浏览器会将用户的浏览历史记录作为先前访问过的 URL 的堆栈公开给本地 JavaScript
在某些情况下,利用History对象,攻击者即可以发现应用程序在服务器端执行的某些检查的结果,例如是否登录

解决方法

在重定向的时候,加入一个随机值参数,像这样:

1
2
3
4
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
int securityR = random.nextInt();
If (!unAuthenticated)
response.sendRedirect("Login.jsp?securityR=" +securityR );

分享到:
Disqus 加载中...

如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理