次の方法で共有


CA3009:XML インジェクションの脆弱性のコード レビュー

プロパティ
ルール ID CA3009
Title XML インジェクションの脆弱性のコード レビュー
[カテゴリ] Security
修正が中断か中断なしであるか なし
.NET 8 では既定で有効 いいえ

原因

信頼できない可能性のある HTTP 要求入力が未加工の XML 出力に到達した場合。

既定で、このルールではコードベース全体を分析しますが、これは構成可能です。

規則の説明

信頼されていない入力を処理するときには、XML インジェクション攻撃に注意してください。 攻撃者は XML インジェクションを使用して XML ドキュメントに特殊文字を挿入し、そのドキュメントを無効な XML にすることができます。 また、攻撃者は、選択した XML ノードを悪意で挿入することもできます。

このルールは、未加工の XML 書き込みに到達する HTTP 要求からの入力の検索を試みます。

注意

このルールでは、アセンブリ間のデータを追跡することはできません。 たとえば、あるアセンブリが HTTP 要求入力を読み取り、未加工の XML を書き込む別のアセンブリにそれを渡す場合、このルールでは警告が生成されません。

注意

このルールでメソッド呼び出し間のデータ フローがどれほど深く分析されるかについては、構成可能な制限があります。 EditorConfig ファイルでこの制限を構成する方法については、「Analyzer Configuration」(Analyzer の構成) を参照してください。

違反の修正方法

違反を修正するには、次のいずれかの手法を使用します。

  • 未加工の 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>

解決策

この違反を修正するには、入力を InnerXml プロパティではなく、ルート要素の InnerText プロパティに設定します。

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

オプションの値で使用できるシンボル名の形式 (| で区切ります):

  • シンボル名のみ (包含する型または名前空間に関係なく、その名前が指定されたすべてのシンボルが含まれます)。
  • そのシンボルのドキュメント ID 形式の完全修飾名。 各シンボル名には、メソッドには M:、型には T:、名前空間には N: のように、シンボルの種類のプレフィックスが必要です。
  • コンストラクターには .ctor、静的コンストラクターには .cctor

例 :

オプション値 まとめ
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType MyType という名前のすべてのシンボルを検索します。
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 MyType1 または MyType2 という名前のすべてのシンボルを検索します。
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) それぞれの完全修飾シグネチャを持つ特定のメソッド MyMethod1 または MyMethod2 を検索します。

特定の型とその派生型を除外する

分析から特定の型とその派生型を除外できます。 たとえば、MyType という名前の型のメソッドとその派生型で規則を実行しないように指定するには、プロジェクトの .editorconfig ファイルに次のキーと値のペアを追加します。

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

オプションの値で使用できるシンボル名の形式 (| で区切ります):

  • 型の名前のみ (包含する型または名前空間に関係なく、その名前が指定されたすべての型が含まれます)。
  • そのシンボルのドキュメント ID 形式の完全修飾名 (オプションで 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 MyType1 または MyType2 という名前のすべての型と、そのすべての派生型を検索します。
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 それぞれの完全修飾名を持つ特定の型 MyType1 または MyType2 と、そのすべての派生型を検索します。