2013-01-09 27 views
20

Chúng tôi đã kiểm tra bảo mật trên mã của chúng tôi và họ đã đề cập rằng mã của chúng tôi dễ bị tấn công EXternal Entity (XXE). Tôi đang sử dụng mã sau -Làm thế nào để ngăn chặn tấn công XXE (XmlDocument in .net)

string OurOutputXMLString= 
"<ce><input><transaction><length>00000</length><tran_type>Login</tran_type></transaction><user><user_id>ce_userid</user_id><subscriber_name>ce_subscribername</subscriber_name><subscriber_id>ce_subscriberid</subscriber_id><group_id>ce_groupid</group_id><permissions></permissions></user><consumer><login_details><username>UnitTester9</username><password>pDhE5AsKBHw85Sqgg6qdKQ==</password><pin>tOlkiae9epM=</pin></login_details></consumer></input></ce>" 

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.LoadXml(OurOutputXMLString); 

Trong báo cáo kiểm tra, họ nói rằng nó không thành công vì thực thể XML có thể chứa URL có thể giải quyết ngoài ngữ cảnh dự định. Trình phân giải đối tượng XML sẽ cố gắng giải quyết và truy xuất các tham chiếu bên ngoài. Nếu XML được kiểm soát bởi kẻ tấn công có thể được gửi đến một trong các chức năng này, thì kẻ tấn công có thể truy cập thông tin về mạng nội bộ, hệ thống tệp cục bộ hoặc các dữ liệu nhạy cảm khác. Để tránh điều này tôi đã viết đoạn mã sau nhưng nó không hoạt động.

MemoryStream stream = 
    new MemoryStream(System.Text.Encoding.Default.GetBytes(OurOutputXMLString)); 

XmlReaderSettings settings = new XmlReaderSettings(); 

settings.DtdProcessing = DtdProcessing.Prohibit; 
settings.MaxCharactersFromEntities = 6000; 
XmlReader reader = XmlReader.Create(stream, settings); 
XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.Load(reader); 

nhưng tôi có thể thấy ở đây người đọc không có bất kỳ giá trị nào để tải vào xmlDoc (XmlDocument). Bất cứ ai có thể giúp đỡ nơi tôi đang thiếu những thứ? Bất kỳ trợ giúp nào được đánh giá cao!

+4

Nếu bạn chắc chắn rằng bạn sẽ không sử dụng tài nguyên bên ngoài, bạn có thể kiểm soát thông tin đăng nhập mà XMLResolver của XmlDocument sử dụng. Xem http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.xmlresolver.aspx để biết ví dụ. Trong trường hợp này, bạn có thể đặt thông tin đăng nhập của XmlResolver vào tài khoản chỉ có quyền truy cập giới hạn, vì vậy mọi nỗ lực truy xuất tài nguyên đều có thể được kiểm soát thông qua quyền NT. – dash

+2

Trong thực tế, đây là một bài viết MSDN rất hữu ích mà địa chỉ câu hỏi của bạn: http://msdn.microsoft.com/en-us/magazine/ee335713.aspx – dash

Trả lời

28

Tài nguyên bên ngoài được giải quyết bằng cách sử dụng XmlResolver được cung cấp qua thuộc tính XmlDocument.XmlResolver. Nếu tài liệu XML của bạn ** không được chứa bất kỳ tài nguyên bên ngoài ** (ví dụ DTD hoặc lược đồ) chỉ cần đặt khách sạn này để null:

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.XmlResolver = null; 
xmlDoc.LoadXml(OurOutputXMLString); 

Nếu bạn muốn lọc nơi các URL đến từ (ví dụ để cho phép chỉ một số miền nhất định) chỉ lấy được lớp của riêng bạn từ XmlUrlResolver và ghi đè phương thức ResolveUri(). Ở đó bạn có thể kiểm tra xem URL là gì và làm vệ sinh nó (ví dụ bạn chỉ có thể cho phép các URL trong mạng nội bộ của bạn hoặc từ các nguồn đáng tin cậy).

Ví dụ:

class CustomUrlResovler : XmlUrlResolver 
{ 
    public override Uri ResolveUri(Uri baseUri, string relativeUri) 
    { 
     Uri uri = new Uri(baseUri, relativeUri); 
     if (IsUnsafeHost(uri.Host)) 
      return null; 

     return base.ResolveUri(baseUri, relativeUri); 
    } 

    private bool IsUnsafeHost(string host) 
    { 
     return false; 
    } 
} 

đâu IsUnsafeHost() là một chức năng tùy chỉnh mà kiểm tra xem các máy chủ nhất định được phép hay không. Xem this post ở đây trên SO cho vài ý tưởng. Chỉ cần trả lại null từ ResolveUri() đến lưu mã của bạn từ loại tấn công này. Trong trường hợp URI được cho phép, bạn chỉ có thể trả về việc thực thi XmlUrlResolver.ResolveUri() mặc định.

Để sử dụng nó:

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.XmlResolver = new CustomUrlResolver(); 
xmlDoc.LoadXml(OurOutputXMLString); 

Để biết thêm chi tiết về cách nguồn lực bên ngoài XML được giải quyết chỉ đọc Resolving External Resources trên MS Documents. Nếu mã của bạn phức tạp hơn ví dụ này thì bạn chắc chắn nên đọc Remarks section cho thuộc tính XmlDocument.XmlResolver.

+0

Wow! Cảm ơn Adriano vì điều này và điều này làm việc cho tôi. Cảm ơn Dash cho thông tin. –

2

Vì vậy, nó tốt hơn để sử dụng

new XmlDocument { XmlResolver = null }; 

Điều thú vị là từ .net 4.5.2 và 4.6, resolver mặc định cư xử khác nhau và không sử dụng một XmlUrlResolver trả trước ngầm để giải quyết bất kỳ url hoặc các địa điểm như tôi nhìn thấy.

//In pre 4.5.2 it is a security issue. 
//In 4.5.2 it will not resolve any more the url references in dtd and such, 
//Still better to avoid the below since it will trigger security warnings. 
new XmlDocument(); 
Các vấn đề liên quan