XML外部实体注入详解|OWASP Top 10安全风险实践(四)

本文为一些列连载文章之一,不定期更新,计划目录如下:

XML外部实体注入

XPATH注入

反射式、DOM及存储XSS

失效的身份认证和会话管理

不安全的直接对象引用

安全配置错误

敏感信息泄露

功能级访问控制缺失

跨站请求伪造

服务端请求伪造

文件上传漏洞

未验证的重定向和转发

不安全的反序列化

使用含有已知漏洞的组件

一、注入

注入攻击漏洞,例如SQL,OS 以及 LDAP注入。这些攻击发生在当不可信的数据作为命令或者查询语句的一部分,被发送给解释器的时候。攻击者发送的恶意数据可以欺骗解释器,以执行计划外的命令或者在未被恰当授权时访问数据。

  1. XML外部实体注入
  • 漏洞利用演示

页面功能:选择并查看xml文件内容。假设选择的evil.xml文件内容为:

XML外部实体注入详解|OWASP Top 10安全风险实践(四)

则结果显示了对应的文件内容和目录内容:

XML外部实体注入详解|OWASP Top 10安全风险实践(四)

  • 漏洞危害说明

    XXE攻击可以执行服务端任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害。

  • 漏洞代码分析
<%        Stringxmlfile=request.getParameter("fileselect");        if(xmlfile ==null){            xmlfile="wah.xml";        }        File f = newFile(application.getRealPath("/") + "/xml/"+xmlfile);        SAXReader reader = newSAXReader();        try {            Document document = reader.read(f);            Element element = document.getRootElement();            Iterator it = element.elementIterator();                                    while(it.hasNext()) {        Object object = (Object) it.next();        out.println("=====开始遍历=====<br />");                             Element ele = (Element) object;        List<Attribute> eleAttrs =ele.attributes();        for (Attributeattr : eleAttrs) {                     out.println("属性名:" +attr.getName() + "--属性值:" +attr.getValue()+"<br />");             }                                        Iterator itt = ele.elementIterator();        while(itt.hasNext()) {             Element eleChild = (Element)itt.next();                     out.println("节点名:" +eleChild.getName() + "--节点值:" +eleChild.getStringValue().replaceAll("rn", "br/>")+"<br/>");             }        out.println("=====结束遍历=====<br />");        }        } catch(DocumentException e) {            e.printStackTrace();        }    %>

后端处理代码中没有禁用DTD或没有对XML文件中可能引用外部实体的关键字进行判断,如果xml文件中,通过定义外部引用变量,指向系统敏感文件或其它地址,则可导致上述漏洞问题发生。

注:代码中未对xmlfile进行验证,存在路径遍历问题。

  • 漏洞代码修复

    防止XXE注入可使用:

a.禁用文档类型定义DTD

<%    String xmlfile=request.getParameter("fileselect");    if(xmlfile ==null){        xmlfile="wah.xml";    }    File f = newFile(application.getRealPath("/") + "/xml/"+xmlfile);    SAXReader reader = newSAXReader();    // 禁止DTD                    reader.setFeature("https://apache.org/xml/features/disallow-doctype-decl",true);     reader.setFeature("https://xml.org/sax/features/external-general-entities",false);  reader.setFeature("https://xml.org/sax/features/external-parameter-entities",false);    try {        Document document = reader.read(f);        Element element =document.getRootElement();        Iterator it = element.elementIterator();        …….%>

b.过滤用户提交的XML数据关键词:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。