开发安全规约(三)——XML最佳安全实践

XML的基本概念

XML 指可扩展标记语言(EXtensible Markup Language),是一种标记语言,很类似 HTML。其设计宗旨是传输数据和存储数据。

DTD指文档类型定义(Document Type Definition),用于声明实体来定义变量(或是文字类的宏),以便在接下来的DTD或者XML文档中多次使用。

ENTITY实体:一般实体用来访问内部资源,而外部实体用来访问外部资源。在解析外部实体的过程中,XML的分析器支持众多网络协议和服务(DNS,FTP,HTTP,SMB等等),这取决于URLs的值。

XML在Java中分两种解析方式:

  • DOM方式:DOM方式是将整个XML以加载到内存中,可随机读写和XPath查找,但非常耗时和占内存,适用小XML文件。
  • SAX方式:SAX是以流的形式读取XML,无需等待整个XML加载,适合读取大XML文件,但只能单向解析,不支持XPath查找和随机访问,不能对原始数据进行修改。

XML的安全隐患

1、拒绝服务攻击

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ENTITY lol "lol">
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

如上图实体 lol9 由 10 个 lol8 组成,由此类推,lol9 为 一亿 个 lol 组成。一个小于1K的XML能消耗3.5G内存。若 lol 定义的字符更长,或阶层更多,可瞬间使服务器宕机。

2、外部实体注入

XML组件默认允许 XML 文档包含来自外部 URI 的数据,例如包含本地计算机或远程系统上的某个文件。当接受用户的输入作为文档的一部分动态构建XML时,防护不当可能导致:

读取任意文件
外传数据
执行系统命令
内网攻击
3、XPath注入

XML支持用XPath查询语句,如://users/user[loginID/text()=’user’ and password/text()=’pwd’],若未严格验证输入,就容易被注入攻击(类似SQL注入)。如://users/user[loginID/text()='admin' and password/text()='' or 1=1 or ''='']

XML的安全加固

1、若在使用XML时,无需使用内联文档类型声明,请禁止DTD,可规避拒绝服务和外部实体注入攻击。

factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

2、若需要使用内联文档类型,请开启安全进程,可避免多层嵌套引起的拒绝服务攻击。

  • 解析器或读取器开启 secure-processing 属性。
factory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
或
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
  • 在 JAXP 1.3 及更早版本中,为 DOM 和 SAX 解析器设置默认限制,例如:
entityExpansionLimit = 64000
elementAttributeLimit = 10000
  • 从 JAXP 1.4 开始,默认开启secure-processing,还增加了 maxOccur 限制。
maxOccur = 5000

3、若需要使用内联文档类型,还需要限制实体类型(需JDK7+)

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

4、若需要使用XPath进行查询,请使用 ESAPI.encoder().encodeForXPath(xpath) 对用户输入进行转义。

推荐阅读更多精彩内容

  • # XML复习 ## 第一章 ## 思考题 **什么是XML?** XML是可扩展性标记语言,XML是标准通用标记...
    冷漠铁锤丁富贵阅读 203评论 0 0
  • 什么是XML? XML:extensiable markup language 被称作可扩展标记语言 XML简单的...
    Java3y阅读 1,962评论 5 41
  • day5 一、表单提交方式 1.使用submit提交 2.使用button提交表单 3.使用超链接提交 4.onc...
    mwj610阅读 160评论 0 0
  • 课程内容:XML 安装MyEclipse开发工具 * 破解(看图) * 配置 * 配置工作空间的编码(UTF-...
    流年划破容颜_cc55阅读 756评论 0 2
  • xml经典总结 XML(eXtensible Markup Language)是万维网联盟(World Wide ...
    java日记阅读 548评论 0 2