System.Xml 安全性考量

更新: November 2007

下列各節將討論使用 System.Xml 元件時可引發的安全性問題類型,以及可執行哪些動作來減緩這些威脅。

注意事項:

System.Xml 元件依賴於 Microsoft .NET Framework 安全性系統。本主題僅解決特別由 XML 類別處理的安全性問題。如需詳細資訊,請參閱 .NET Framework 中的安全性

  • XmlResolver 類別

  • XmlReader 及 XmlReaderSettings 類別

  • XmlTextReader 類別

  • XslCompiledTransform 類別

  • Document Object Model

XmlResolver 類別

XmlResolver 類別可用於解析資源。它還可以用於載入 XML 文件、解析外部資源 (如實體、DTD 或結構描述) 及匯入或併入指示詞。.NET Framework 包括 XmlResolver 類別的兩個實作。

XmlUrlResolver 類別是 System.Xml 命名空間中所有類別的預設解析程式。它支援 file:// 及 http:// 通訊協定,以及 WebRequest 類別的要求。在許多情況下,如果您未指定應用程式應使用的 XmlResolver 物件,則會使用不具使用者認證的 XmlUrlResolver 物件來存取 XML 資源。

XmlSecureResolver 類別可以協助保護另一 XmlResolver 物件,其方法為包裝該 XmlResolver 物件,並限制基礎 XmlResolver 可以存取的資源。例如,XmlSecureResolver 類別可以禁止存取特定的網際網路網站或區域。

使用 XmlResolver 類別時,應考量下列項目。

  • XmlResolver 物件可以包含機密資訊,如可用於存取及擷取資料的使用者認證。快取 XmlResolver 物件時請務必小心,請勿將 XmlResolver 物件傳遞至不受信任的元件,因為不受信任的元件可以使用 XmlResolver 及其使用者認證來存取資料。

  • 如果設計使用 XmlResolver 類別的類別屬性,應將屬性定義為唯寫屬性。該屬性可用於指定要使用的 XmlResolver,但其不可用於傳回 XmlResolver 物件。如此可讓不受信任的元件使用類別,但不會允許它擷取及直接使用 XmlResolver 物件。

  • 如果應用程式接受來自不受信任之程式碼的 XmlResolver 物件,則您無法假設傳入 GetEntity 方法的 URI 與 ResolveUri 方法傳回的 URI 相同。從 XmlResolver 類別衍生的類別可以覆寫 GetEntity 方法,並傳回與原始 URI 所包含之內容不同的資料。

  • 應用程式可減緩 GetEntity 方法的記憶體阻斷服務威脅,其方法是對可實作換行的 IStream (其會限制讀取的位元組數) 進行實作。這有助於防止惡意程式碼嘗試將無限的位元組資料流傳遞至 GetEntity 方法。

XmlReader 及 XmlReaderSettings 類別

實際上,所有 System.Xml 元件都是依據剖析 XML 的概念而建置的。例如,XmlDocument 類別使用 XmlReader 類別來剖析文件,並建置 XML文件的記憶體中表示法。

建議使用 Create 方法建立 XmlReader 物件。XmlReaderSettings 類別可以指定要在 XmlReader 物件上啟用的一組功能。

限制文件和實體擴充大小

使用 XmlReader 之應用程式的記憶體使用量可能與剖析的 XML 文件大小相互關聯。一種形式的阻絕服務攻擊發生於送出過多的 XML 文件進行剖析時。

當使用 XmlReader 時,您可以限制文件的大小,該文件可藉由設定 MaxCharactersInDocument 屬性來加以剖析。您可以藉由設定 MaxCharactersFromEntities 屬性來限制從擴充實體所產生的字元數目。如需設定這些屬性的範例,請參閱適當的參考主題。

DTD 處理

DTD 處理可能導致 DoS 條件。例如,DTD 可能包含需耗費大量時間來處理的巢狀實體或複雜內容模型。

DTD 處理預設會停用。當 XmlReader 發現 DTD 資料時,會擲回 XmlException

結構描述處理

依預設,不會設定 XmlReaderSettings 物件的 ProcessInlineSchemaProcessSchemaLocation 驗證旗標。在處理來自不受信任來源的 XML 資料時,這有助於保護 XmlReader,防止其遭受以結構描述為基礎的攻擊。當設定這些旗標時,XmlReaderSettings 物件的 XmlResolver 可用於解析在 XmlReader 的執行個體文件中發現的結構描述位置。如果 XmlResolver 屬性設為 null,則即使設定 ProcessInlineSchemaProcessSchemaLocation 驗證旗標,也不會解析結構描述位置。

在驗證期間加入的結構描述會加入新的型別,而且可變更所驗證文件的驗證結果。因此,外部結構描述應僅從受信任的來源解析。

當在可用性高的情況下,針對在文件的大部分具有識別條件約束的結構描述,驗證大量不受信任的 XML 文件時,建議停用 ProcessIdentityConstraints 旗標 (預設會啟用)。

外部資源

XML 資料可以包括外部資源的參考,如結構描述檔案。依預設,外部資源會使用不具使用者認證的 XmlUrlResolver 物件來解析。也就是說,依預設,您可以存取不需要認證的任何位置。您可以藉由執行下列其中一項,進一步確保這一點:

共用 XmlReaderSettings 物件

XmlReaderSettings 物件可以包含機密資訊 (如使用者認證)。不受信任的元件可能會使用 XmlReaderSettings 物件及其使用者認證,建立 XmlReader 物件來讀取資料。快取 XmlReaderSettings 物件,或將 XmlReaderSettings 物件從一個元件傳遞至另一元件時,請務必小心。

支援元件

資料處理

XML 資料可以包含需要相當長時間來處理的大量屬性、命名空間宣告、巢狀項目等。

  • 您可以建立可限制所使用之輸入大小的自訂 IStream 實作,並將其提供給 XmlReader 類別。

  • 使用 ReadValueChunk 方法可以處理大量資料流。此方法每次會讀取較少數量的字元,而不是為整個值配置單一字串。

XmlTextReader 類別

XmlTextReader 類別是 XmlReader 類別的舊版實作。

DTD 處理

DTD 處理預設會啟用。若要停用 DTD 處理,請將 ProhibitDtd 屬性設為 true。

實體處理

依預設不會展開一般實體。當呼叫 ResolveEntity 方法時,會展開一般實體。

外部資源

XML 資料可以包括外部資源的參考,如 DTD 參考。依預設,外部資源會使用不具使用者認證的 XmlUrlResolver 物件來解析。

您可以藉由執行下列其中一項,進一步確保這一點:

XslCompiledTransform 類別

XslCompiledTransform 類別是支援 XSLT 1.0 語法的 XSLT 處理器。它可讓您使用 XSLT 樣式表來轉換 XML 資料。

外部資源

樣式表可以包括外部資源的參考,如 xsl:import 或 xsl:include 項目,或 document() 函式。

XslCompiledTransform 類別預設會支援 xsl:import 或 xsl:include 項目。XslCompiledTransform 類別預設會停用對 document() 函式的支援。XsltSettings 類別可用於啟用 document() 函式。

LoadTransform 方法包括將 XmlResolver 物件做為其中一個引數的多載。如果未指定 XmlResolver,則會使用沒有任何認證的預設 XmlUrlResolver

您可以藉由執行下列其中一項,控制如何存取外部資源:

  • 藉由使用 XmlSecureResolver 物件,限制 XSLT 處理序可存取的資源。

  • 藉由將 null 傳入至 XmlResolver 引數,來禁止 XSLT 處理序開啟任何外部資源。

指令碼區塊

XslCompiledTransform 類別預設不支援指令碼區塊。使用 XsltSettings 類別可以啟用指令碼區塊。僅當需要指令碼支援且在完全受信任的環境中運作時,才應啟用 XSLT 指令碼。

擴充物件

擴充物件可將程式設計功能加入 XSLT 轉換。預設會啟用此功能。如果將擴充物件傳遞至 Transform 方法,則會在 XSLT 轉換中使用它們。

文件物件模型

因為文件物件模型 (DOM) 會快取記憶體中的所有資料,所以如果您正使用不受信任的資料,而且顧慮阻斷服務攻擊,則建議您不要執行 DOM 作業 (如查詢、編輯、在文件之間移動樹狀子目錄及儲存 DOM 物件)。另一個選擇是為可讀取至 DOM 中的資料數量設定限制。完成此動作的一種方法是建立限制所使用之輸入大小的自訂資料流實作,並使用其來載入 DOM 物件。

XmlDocument 物件可以包含機密資訊 (如內嵌 XmlResolver 物件中的使用者認證)。如果將 XmlDocument.XmlResolver 屬性設為具有使用者認證的XmlResolver 物件,則不應快取 XmlDocument 物件,或將其傳遞至不受信任的元件。不受信任的元件可能會使用 DOM 物件及內嵌 XmlResolver 使用者認證來存取及載入資料。

請參閱

概念

System.Xml 程式碼撰寫方針