CA3009:檢閱程式碼是否有 XML 插入式攻擊弱點

屬性
規則識別碼 CA3009
標題 檢閱程式碼是否有 XML 插入式攻擊弱點
類別 安全性
修正程式是中斷或非中斷 不中斷
預設在 .NET 8 中啟用 No

原因

可能不受信任的 HTTP 要求輸入會到達原始 XML 輸出。

根據預設,此規則會分析整個程式代碼基底,但這是可設定

檔案描述

使用不受信任的輸入時,請留意 XML 插入式攻擊。 攻擊者可以使用 XML 插入將特殊字元插入 XML 檔中,使文件無效。 或者,攻擊者可能會惡意插入其選擇的 XML 節點。

此規則會嘗試從到達原始 XML 寫入的 HTTP 要求尋找輸入。

注意

此規則無法追蹤元件之間的數據。 例如,如果某個元件讀取 HTTP 要求輸入,然後將它傳遞至寫入原始 XML 的另一個元件,則此規則不會產生警告。

注意

此規則在方法呼叫之間分析數據流的深度有可設定的限制。 如需如何在EditorConfig檔案中設定限制,請參閱 分析器 組態。

如何修正違規

若要修正違規,請使用下列其中一種技術:

  • 請勿撰寫原始 XML。 請改用 XML 編碼其輸入的方法或屬性。
  • 撰寫原始 XML 之前,XML 編碼輸入。
  • 使用基本類型轉換和 XML 編碼的清理工具來驗證用戶輸入。

隱藏警告的時機

請勿隱藏此規則的警告。

虛擬程式代碼範例

違規

在此範例中,輸入會設定為 InnerXml 根元素的 屬性。 給定包含有效 XML 的輸入,惡意使用者就可以完全改變檔。 請注意, alice 在使用者輸入新增至文件之後,不再是允許的使用者。

protected void Page_Load(object sender, EventArgs e)
{
    XmlDocument d = new XmlDocument();
    XmlElement root = d.CreateElement("root");
    d.AppendChild(root);

    XmlElement allowedUser = d.CreateElement("allowedUser");
    root.AppendChild(allowedUser);
    allowedUser.InnerXml = "alice";

    string input = Request.Form["in"];
    root.InnerXml = input;
}
Sub Page_Load(sender As Object, e As EventArgs)
    Dim d As XmlDocument = New XmlDocument()
    Dim root As XmlElement = d.CreateElement("root")
    d.AppendChild(root)

    Dim allowedUser As XmlElement = d.CreateElement("allowedUser")
    root.AppendChild(allowedUser)
    allowedUser.InnerXml = "alice"

    Dim input As String = Request.Form("in")
    root.InnerXml = input
End Sub

如果攻擊者將此專案用於輸入: some text<allowedUser>oscar</allowedUser>,則 XML 檔會是:

<root>some text<allowedUser>oscar</allowedUser>
</root>

解決方案

若要修正此違規,請將輸入設定為 InnerText 根元素的 屬性,而不是 InnerXml 屬性。

protected void Page_Load(object sender, EventArgs e)
{
    XmlDocument d = new XmlDocument();
    XmlElement root = d.CreateElement("root");
    d.AppendChild(root);

    XmlElement allowedUser = d.CreateElement("allowedUser");
    root.AppendChild(allowedUser);
    allowedUser.InnerText = "alice";

    string input = Request.Form["in"];
    root.InnerText = input;
}
Sub Page_Load(sender As Object, e As EventArgs)
    Dim d As XmlDocument = New XmlDocument()
    Dim root As XmlElement = d.CreateElement("root")
    d.AppendChild(root)

    Dim allowedUser As XmlElement = d.CreateElement("allowedUser")
    root.AppendChild(allowedUser)
    allowedUser.InnerText = "alice"

    Dim input As String = Request.Form("in")
    root.InnerText = input
End Sub

如果攻擊者將此專案用於輸入: some text<allowedUser>oscar</allowedUser>,則 XML 檔會是:

<root>some text&lt;allowedUser&gt;oscar&lt;/allowedUser&gt;
<allowedUser>alice</allowedUser>
</root>

設定程式代碼以分析

使用下列選項來設定程式代碼基底要執行此規則的部分。

您可以只針對此規則、它套用的所有規則,或針對套用至此類別的所有規則(安全性)設定這些選項。 如需詳細資訊,請參閱 程式代碼品質規則組態選項

排除特定符號

您可以從分析中排除特定符號,例如類型和方法。 例如,若要指定規則不應該在名為 MyType的任何程式代碼上執行,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

選項值中允許的符號名稱格式(以 |分隔):

  • 只包含符號名稱(包含名稱的所有符號,不論包含類型或命名空間為何)。
  • 符號 檔案識別碼格式的完整名稱。 每個符號名稱都需要符號種類前置詞,例如 M: 方法、 T: 類型和 N: 命名空間。
  • .ctor 用於建構函式和 .cctor 靜態建構函式。

範例:

選項值 摘要
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType 符合所有名為 MyType的符號。
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 比對名為 MyType1MyType2的所有符號。
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) 比對特定方法 MyMethod 與指定的完整簽章。
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) 比對特定方法和MyMethod1MyMethod2個別的完整簽章。

排除特定類型及其衍生類型

您可以從分析中排除特定類型及其衍生類型。 例如,若要指定規則不應該在具名 MyType 類型及其衍生型別內的任何方法上執行,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

選項值中允許的符號名稱格式(以 |分隔):

  • 僅限類型名稱(包含名稱的所有類型,不論包含類型或命名空間為何)。
  • 符號 文件識別碼格式的完整名稱,具有選擇性 T: 前置詞。

範例:

選項值 摘要
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType 比對所有具名 MyType 的類型及其所有衍生型別。
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 比對所有名為 MyType1MyType2 的型別,以及其所有衍生型別。
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType 比對具有指定完整名稱的特定型 MyType 別及其所有衍生型別。
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 比對特定類型和MyType1MyType2個別的完整名稱,以及其所有衍生型別。