防范XXE漏洞:XXE攻击详解与应对策略

admin 2025年1月3日00:36:03评论49 views字数 4455阅读14分51秒阅读模式

一、XXE 漏洞概述

XML(可扩展标记语言)是一种用于标记电子文件的结构化语言,它能够对数据进行标记并定义数据类型。XML允许用户自定义标记语言,因此在数据交换和存储中被广泛使用。

1.1 XML 文档结构

XML文档的基本结构包括以下几个部分:

  1. XML 声明 :指定 XML 的版本和编码方式。
  2. DTD(文档类型定义) :可选部分,定义 XML 文档的合法构建模块,可以在文档内部声明,也可以外部引用。
  3. 文档元素 :具体数据的组织和标记。

1.2 XXE 漏洞及其危害

XXE(XML External Entity)漏洞是一个严重的安全漏洞。当应用程序允许 XML 引用外部实体时,恶意用户可以构造特定内容,从而导致以下危害:

  1. 读取系统上的任意文件。
  2. 执行系统命令。
  3. 探测内网端口,获取网络信息。
  4. 进行针对内网网站的攻击。

二、漏洞示例

2.1 示例代码

如下代码主要功能是接收XML内容,通过XML解析器将其解析为DOM对象,并最终将该DOM对象转换为字符串进行返回。代码并没有对XML内容的安全性检验。

import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import org.w3c.dom.Document;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.transform.OutputKeys;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.StringWriter;@RestControllerpublic class XmlController {    @PostMapping("/parse-xml")    public String parseXml(@RequestBody String xmlContent) {        try {            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();            DocumentBuilder builder = factory.newDocumentBuilder();            Document doc = builder.parse(new ByteArrayInputStream(xmlContent.getBytes()));            // 打印 Document 的内容return convertDocumentToString(doc);        } catch (Exception e) {return"Error parsing XML: " + e.getMessage();        }    }    // 将 Document 转换为字符串    private String convertDocumentToString(Document doc) {        try {            TransformerFactory transformerFactory = TransformerFactory.newInstance();            Transformer transformer = transformerFactory.newTransformer();            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");            transformer.setOutputProperty(OutputKeys.INDENT, "yes");            StringWriter writer = new StringWriter();            transformer.transform(new DOMSource(doc), new StreamResult(writer));return writer.getBuffer().toString();        } catch (Exception e) {return"Error converting Document to String: " + e.getMessage();        }    }}

2.2 接口请求

  • 如下是发送的请求包,读取本地文件
POST /parse-xml HTTP/1.1Host: localhost:8000Content-Type: application/xmlContent-Length: 159<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [  <!ENTITY xxe SYSTEM "file:///etc/passwd"> <!-- 读取本地文件的示例 -->]><foo>&xxe;</foo>
  • 接口返回的内容防范XXE漏洞:XXE攻击详解与应对策略

  • 如下请求,探测地址,本次请求,使用DNSLog探测

POST /parse-xml HTTP/1.1Host: localhost:8000Content-Type: application/xmlContent-Length: 176<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [  <!ENTITY xxe SYSTEM "http://6223dbe1.log.dnslog.sbs/"> <!-- 这里可以替换为任意 URL -->]><foo>&xxe;</foo>
  • 发现服务器请求了这个域名地址(可以用于内部端口探测)
防范XXE漏洞:XXE攻击详解与应对策略

三、修复建议

  1. 使用开发语言提供的禁用外部实体的方法。确保在解析XML前禁用DTD(文档类型定义)和禁止外部实体的解析。
  2. 过滤用户提交的XML数据,特别是对于嵌入XML或DTD的输入,进行严格的验证和过滤,确保它们不包含对外部实体或不安全的结构的引用。

3.1 Java代码示例

// bad@RequestMapping("/xxe")public void test(String xmlstr) throws  IOException {    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    try {        InputStream is = new ByteArrayInputStream(xmlstr.getBytes());        DocumentBuilder builder = factory.newDocumentBuilder();        builder.parse(is);    } catch (Exception e) {        e.printStackTrace();    }}// good@RequestMapping("/no_xxe")public void test(String xmlstr) throws  IOException {    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    try {        // 禁用DTD、禁止外部实体解析        factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl"true);        factory.setFeature("http://xml.org/sax/features/external-general-entities"false);        factory.setFeature("http://xml.org/sax/features/external-parameter-entities"false);        InputStream is = new ByteArrayInputStream(xmlstr.getBytes());        DocumentBuilder builder = factory.newDocumentBuilder();        builder.parse(is);    } catch (Exception e) {        e.printStackTrace();    }}

3.2 PHP代码示例

// good:加载XML前,禁用实体解析libxml_disable_entity_loader(true);$$xml = simplexml_load_string($$xmlContent);

3.3 Python代码示例

// good 禁用外部实体from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

四、总结

在当今网络安全形势日益严峻的环境中,XXE(XML External Entity)漏洞作为一种常见的XML解析安全问题,得到了越来越多的关注。 首先,XXE漏洞利用了XML解析器在处理外部实体时的安全缺陷,攻击者可以通过精心构造的XML文档,读取系统内部敏感文件、执行任意命令,甚至进行内部网络探测。一旦系统遭到攻击,可能导致数据泄露、服务中断甚至更为严重的后果,因此,了解并防范XXE漏洞非常重要。 针对这一漏洞,禁用DTD及外部实体的解析是最直接且有效的方式。此外,通过严格的输入验证和过滤,提升解析器的安全性,也能有效降低潜在的风险。作为开发者,理解如何安全地处理XML数据,不仅仅是编写代码的一部分,更是保护用户数据和维护系统安全的重要责任。

参考文档

  • XML 语法 https://www.runoob.com/xml/xml-syntax.html
  • DTD 教程 https://www.runoob.com/dtd/dtd-tutorial.html
  • XMLReader https://docs.oracle.com/javase/8/docs/api/org/xml/sax/XMLReader.html

原文始发于微信公众号(SDL安全):防范XXE漏洞:XXE攻击详解与应对策略

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月3日00:36:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   防范XXE漏洞:XXE攻击详解与应对策略https://cn-sec.com/archives/3586665.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息