英語で読む

次の方法で共有


CA2322:逆シリアル化する前に JavaScriptSerializer が SimpleTypeResolver によって初期化されていないことを確認してください

プロパティ
ルール ID CA2322
Title 逆シリアル化する前に JavaScriptSerializer が SimpleTypeResolver によって初期化されていないことを確認してください
[カテゴリ] Security
修正が中断か中断なしであるか なし
.NET 9 では既定で有効 いいえ

原因

System.Web.Script.Serialization.JavaScriptSerializer 逆シリアル化メソッドが呼び出されたか参照され、JavaScriptSerializerSystem.Web.Script.Serialization.SimpleTypeResolver を使用して初期化されている可能性があります。

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

規則の説明

安全でない逆シリアライザーは、信頼されていないデータを逆シリアル化するときに脆弱です。 攻撃者がシリアル化されたデータを変更して予期されない型を追加し、悪意のある副作用を持つオブジェクトを挿入する可能性があります。 たとえば、安全でない逆シリアライザーに対する攻撃では、基になるオペレーティング システムでコマンドが実行されたり、ネットワークを介して通信されたり、ファイルを削除されたりする可能性があります。

この規則は、System.Web.Script.Serialization.JavaScriptSerializerJavaScriptSerializer を使用して初期化されている可能性がある場合に、System.Web.Script.Serialization.SimpleTypeResolver 逆シリアル化メソッド呼び出しまたは参照を検索します。

違反の修正方法

  • JavaScriptTypeResolver オブジェクトが System.Web.Script.Serialization.SimpleTypeResolver を使用して初期化されないようにします。
  • コードで SimpleTypeResolver を使用してシリアル化されたデータを読み取る必要がある場合は、カスタム JavaScriptTypeResolver を実装することで、逆シリアル化された型を予期されるリストに制限します。
  • シリアル化されたデータを改ざん防止にします。 シリアル化後に、シリアル化されたデータに暗号化署名します。 逆シリアル化する前に、暗号化署名を検証します。 暗号化キーの開示を防止し、キーのローテーションを設計します。

どのようなときに警告を抑制するか

次の場合は、このルールの警告を抑制できます。

  • 入力が信頼されていることがわかっている。 アプリケーションの信頼境界とデータ フローは時間の経過と共に変わる可能性があることを考慮する。
  • 違反を修正する方法のいずれかの予防措置を講じた。

警告を抑制する

単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。

C#
#pragma warning disable CA2322
// The code that's violating the rule is on this line.
#pragma warning restore CA2322

ファイル、フォルダー、またはプロジェクトの規則を無効にするには、noneでその重要度を に設定します。

ini
[*.{cs,vb}]
dotnet_diagnostic.CA2322.severity = none

詳細については、「コード分析の警告を抑制する方法」を参照してください。

分析するコードを構成する

次のオプションを使用して、コードベースのどの部分に対してこのルールを実行するかを構成します。

これらのオプションは、このルールのみ、適用されるすべてのルール、または適用先のこのカテゴリ (セキュリティ) のすべてのルールに対して構成できます。 詳細については、「コード品質規則の構成オプション」を参照してください。

特定のシンボルを除外する

excluded_symbol_names オプションを設定することで、種類やメソッドなどの特定のシンボルを分析から除外できます。 たとえば、MyType という名前の型のコードで規則を実行しないように指定するには、プロジェクトの .editorconfig ファイルに次のキーと値のペアを追加します。

ini
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

注意

CAXXXXXXXX 部分を該当するルールの ID に置き換えます。

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

  • シンボル名のみ (包含する型または名前空間に関係なく、その名前が指定されたすべてのシンボルが含まれます)。
  • そのシンボルのドキュメント 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 を検索します。

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

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

ini
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

注意

CAXXXXXXXX 部分を該当するルールの ID に置き換えます。

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

  • 型の名前のみ (包含する型または名前空間に関係なく、その名前が指定されたすべての型が含まれます)。
  • そのシンボルのドキュメント 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 と、そのすべての派生型を検索します。

疑似コードの例

違反 1

C#
using System.Web.Script.Serialization;

public class ExampleClass
{
    public JavaScriptSerializer Serializer { get; set; }

    public T Deserialize<T>(string str)
    {
        return this.Serializer.Deserialize<T>(str);
    }
}

解決策 1

C#
using System.Web.Script.Serialization;

public class ExampleClass
{
    public T Deserialize<T>(string str)
    {
        JavaScriptSerializer s = new JavaScriptSerializer();
        return s.Deserialize<T>(str);
    }
}

違反 2

C#
using System.Web.Script.Serialization;

public class BookRecord
{
    public string Title { get; set; }
    public string Author { get; set; }
    public int PageCount { get; set; }
    public AisleLocation Location { get; set; }
}

public class AisleLocation
{
    public char Aisle { get; set; }
    public byte Shelf { get; set; }
}

public class ExampleClass
{
    public JavaScriptSerializer Serializer { get; set; }

    public BookRecord DeserializeBookRecord(string s)
    {
        return this.Serializer.Deserialize<BookRecord>(s);
    }
}

解決策 2

C#
using System;
using System.Web.Script.Serialization;

public class BookRecordTypeResolver : JavaScriptTypeResolver
{
    // For compatibility with data serialized with a JavaScriptSerializer initialized with SimpleTypeResolver.
    private static readonly SimpleTypeResolver Simple = new SimpleTypeResolver();

    public override Type ResolveType(string id)
    {
        // One way to discover expected types is through testing deserialization
        // of **valid** data and logging the types used.

        ////Console.WriteLine($"ResolveType('{id}')");

        if (id == typeof(BookRecord).AssemblyQualifiedName || id == typeof(AisleLocation).AssemblyQualifiedName)
        {
            return Simple.ResolveType(id);
        }
        else
        {
            throw new ArgumentException("Unexpected type ID", nameof(id));
        }
    }

    public override string ResolveTypeId(Type type)
    {
        return Simple.ResolveTypeId(type);
    }
}

public class BookRecord
{
    public string Title { get; set; }
    public string Author { get; set; }
    public int PageCount { get; set; }
    public AisleLocation Location { get; set; }
}

public class AisleLocation
{
    public char Aisle { get; set; }
    public byte Shelf { get; set; }
}

public class ExampleClass
{
    public BookRecord DeserializeBookRecord(string s)
    {
        JavaScriptSerializer serializer = new JavaScriptSerializer(new BookRecordTypeResolver());
        return serializer.Deserialize<BookRecord>(s);
    }
}

CA2321:SimpleTypeResolver を使って JavaScriptSerializer で逆シリアル化しないでください