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)
对用户输入进行转义。