美文网首页JAVA安全开发规约
开发安全规约(三)——XML最佳安全实践

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

作者: Franchen | 来源:发表于2019-10-16 21:32 被阅读0次

    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最佳安全实践

        本文链接:https://www.haomeiwen.com/subject/ybhpmctx.html