次の方法で共有


CA3003:ファイル パス インジェクションの脆弱性のコード レビュー

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

原因

信頼できない可能性のある HTTP 要求入力がファイル操作のパスに到達した場合。

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

規則の説明

Web 要求からの信頼されていない入力を処理するときには、ユーザー制御の入力の使用に注意してください。 攻撃者によって意図しないファイルが読み取られ、機密データの情報漏えいにつながるおそれがあります。 また、攻撃者によって意図しないファイルへの書き込みが行われ、機密データの無断変更やサーバーのセキュリティ侵害を招くおそれがあります。 攻撃者がよく用いるのは、意図したディレクトリ外のファイルにアクセスするパス トラバーサルという手法です。

このルールは、ファイル操作のパスに到達する HTTP 要求からの入力の検索を試みます。

注意

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

注意

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

違反の修正方法

  • 可能であれば、明示的に知られているセーフ リストへのユーザーによる入力に基づいてファイル パスを制限する。 たとえば、アプリケーションでアクセスする必要があるのは "red.txt"、"green.txt"、または "blue.txt" のみである場合は、それらの値のみを許可します。
  • 信頼されていないファイル名を確認し、名前が正しい形式であることを検証する。
  • パスを指定するときは、完全なパス名を使用する。
  • path 環境変数などの、危険性のあるコンストラクトを避ける。
  • 長いファイル名のみを許可し、ユーザーが短い名前を送信する場合は長い名前を検証する。
  • エンド ユーザーによる入力を有効な文字に制限する。
  • MAX_PATH の長さを越える名前を拒否する。
  • ファイル名を、解釈せずに文字どおりに処理する。
  • ファイル名がファイルとデバイスのどちらを表しているかを判断する。

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

前のセクションの説明に従って入力を検証した場合は、この警告を抑制できます。

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

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

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

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

型やメソッドなど、特定のシンボルを分析から除外することができます。 たとえば、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 と、そのすべての派生型を検索します。

疑似コードの例

違反

using System;
using System.IO;

public partial class WebForm : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string userInput = Request.Params["UserInput"];
        // Assume the following directory structure:
        //   wwwroot\currentWebDirectory\user1.txt
        //   wwwroot\currentWebDirectory\user2.txt
        //   wwwroot\secret\allsecrets.txt
        // There is nothing wrong if the user inputs:
        //   user1.txt
        // However, if the user input is:
        //   ..\secret\allsecrets.txt
        // Then an attacker can now see all the secrets.

        // Avoid this:
        using (File.Open(userInput, FileMode.Open))
        {
            // Read a file with the name supplied by user
            // Input through request's query string and display
            // The content to the webpage.
        }
    }
}
Imports System
Imports System.IO

Partial Public Class WebForm
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs)
        Dim userInput As String = Me.Request.Params("UserInput")
        ' Assume the following directory structure:
        '   wwwroot\currentWebDirectory\user1.txt
        '   wwwroot\currentWebDirectory\user2.txt
        '   wwwroot\secret\allsecrets.txt
        ' There is nothing wrong if the user inputs:
        '   user1.txt
        ' However, if the user input is:
        '   ..\secret\allsecrets.txt
        ' Then an attacker can now see all the secrets.

        ' Avoid this:
        Using File.Open(userInput, FileMode.Open)
            ' Read a file with the name supplied by user
            ' Input through request's query string and display
            ' The content to the webpage.
        End Using
    End Sub
End Class