XML外部实体注入
漏洞案例
漏洞描述
安全编码
XXE (XML External Entity Injection), XML外部实体注入,当开发人员配置其XML解析功能允许外部实体引用时,攻击者可利用这一可引发安全问题的配置方式,实施任意文件读取、内网端口探测、命令执行、拒绝服务等攻击。
【必须】XML解析器关闭DTD解析 读取外部传入XML文件时,XML解析器初始化过程中设置关闭DTD解析。 参考示例: xxx.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
运行
漏洞代码 - XMLReader
@RequestMapping(value = "/XMLReader") public String XMLReader(@RequestBody String content) { try { XMLReader xmlReader = XMLReaderFactory.createXMLReader(); // 修复:禁用外部实体 // xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); xmlReader.parse(new InputSource(new StringReader(content))); return "XMLReader XXE"; } catch (Exception e) { return e.toString(); } }
运行
漏洞代码 - SAXReader
SAXReader sax = new SAXReader(); // 修复:禁用外部实体 // sax.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); sax.read(new InputSource(new StringReader(content)));
运行
漏洞代码 - SAXBuilder
@RequestMapping(value = "/SAXBuilder") public String SAXBuilder(@RequestBody String content) { try { SAXBuilder saxbuilder = new SAXBuilder(); // 修复: saxbuilder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); saxbuilder.build(new InputSource(new StringReader(content))); return "SAXBuilder XXE"; } catch (Exception e) { return e.toString(); } }
运行
漏洞代码 - DocumentBuilder
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 修复: dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder builder = factory.newDocumentBuilder();
运行
漏洞代码 - Unmarshaller
/** * PoC * Content-Type: application/xml * ]>
&out;
*/ public String Unmarshaller(@RequestBody String content) { try { JAXBContext context = JAXBContext.newInstance(Student.class); Unmarshaller unmarshaller = context.createUnmarshaller(); XMLInputFactory xif = XMLInputFactory.newFactory(); // 修复: 禁用外部实体 // xif.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // xif.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(content)); Object o = unmarshaller.unmarshal(xsr); return o.toString(); } catch (Exception e) { e.printStackTrace(); }