2016-11-17 306 views
2

我們對我們的代碼進行了安全審計,他們提到我們的代碼易受外部實體(XXE)攻擊。如何防止XXE攻擊

說明- XML外部實體攻擊受益於XML特性,以便在處理時動態構建文檔。 XML 實體允許從給定資源動態地包含數據。外部實體允許XML文檔包含來自外部URI的數據 。除非進行了其他配置,否則外部實體會迫使XML解析器通過URI訪問指定的資源 ,例如本地機器上或遠程系統上的文件。此行爲將應用程序暴露給XML實體(XXE)攻擊,該攻擊可用於執行本地系統的拒絕服務,未經授權訪問本地計算機上的文件,掃描遠程計算機並執行拒絕服務遠程系統。 以下XML文檔顯示XXE攻擊的示例。

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE foo [ 
<!ELEMENT foo ANY > 
<!ENTITY xxe SYSTEM "file:///dev/random" >]><foo>&xxe;</foo> 

此示例可能崩潰的服務器(在UNIX系統上),如果XML解析器嘗試與的 在/ dev /隨機文件的內容來替代實體。

建議- 應該安全地配置XML解組器,以便它不允許外部實體作爲傳入XML文檔的一部分。 爲了避免XXE注入,請不要使用直接將java.io.File,java.io.Reader或 java.io.InputStream處理XML源的解組方法。與安全配置的解析器解析文檔並使用接受的安全

解析器作爲XML源作爲顯示在下面的例子的解組方法:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setExpandEntityReferences(false); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document document = db.parse(<XML Source>); 
Model model = (Model) u.unmarshal(document); 

而編寫的代碼是下面其中發現XXE攻擊 -

Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
System.out.println("outputing to : " + outputLocation); 
File outputFile = new File(outputLocation); 
StreamResult result = new StreamResult(outputFile); 
DOMSource source = new DOMSource(doc); 
transformer.transform(source, result); 

請幫助我如何在我的代碼中實現以上建議。

任何人都可以幫助我失去東西的地方嗎?任何人幫助表示讚賞!

回答

1

您需要打開TransformerFactory上的安全處理功能。它會限制某些可能是惡意的事情發生(DOS攻擊等)

TransformerFactory tf = TransformerFactory.newInstance(); 
tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 
Transformer transformer = tf.newTransformer(); 
+0

感謝您的迴應,是的,但我需要在現有的邏輯中實現DocumentBuilderFactory .... btw我用你的給出的建議,但得到錯誤「方法setFeature(字符串,布爾)是未定義的類型變壓器」。 – SANNO

+0

呃,對不起,您需要將其設置在TransformerFactory中。 – Kayaman

+0

謝謝卡亞曼!其工作正常,但你可以幫助用DocumentBuilderFactory概念取代TransformerFactory概念。真的會是可觀的。 – SANNO

0

您可以使用同樣的方法與DocumentBuilderFactory

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 
... 

爲了讓大家自動使用這個,你需要創建自己的實現(通過擴展你正在使用的那個;使用你的調試器來查明)。在構造函數中設置該功能。

然後,您可以將新工廠傳遞給Java虛擬機的系統屬性javax.xml.parsers.DocumentBuilderFactory,並且每個人都將使用它。