9

呼び出されたときにファイルを削除する Web メソッドがあり、3 つのパラメーター (cNum、year、および fileName) を受け入れるとします。この方法の悪用について心配する必要がありますか。私が考えることができる唯一のことは..\..\..\、削除をフォルダー構造のさらに上に移動するために使用することです。それを削除するのはかなり簡単なはずです。しかし、私が心配する必要があることは他にありますか?

[WebMethod(EnableSession = true, 
           Description = "Method for deleting files uploaded by customers")]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
    try
    {
        if (String.IsNullOrEmpty(cNum) 
            || String.IsNullOrEmpty(year) 
            || String.IsNullOrEmpty(fileName))
                throw new Exception();

        string path = Server.MapPath(@"~\docs\custFiles\" 
                                        + year + @"\" 
                                        + cNum + @"\" + fileName);
        File.Delete(path);
    }
    catch
    {
        throw new Exception("Unable to delete file");
    }
    return true;
}
4

3 に答える 3

12

次のように、クラスのGetFileNameメソッドを使用してファイル名パラメーターをクレンジングすることをお勧めします。Path

public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
    // Cleanse fileName.
    fileName = Path.GetFileName(fileName);

このGetFileNameメソッドは、パスからすべてのディレクトリ情報を取り除きます。これは、まさにここで実行したいことです。

次のような入力で:

..\..\..\filename.ext

あなたは得るでしょう:

filename.ext

その見返りとして、ターゲットとするディレクトリをエスケープするパスを誰かが挿入することを心配する必要はありません(このファイル名がユーザー入力であるか、誰かが必要な入力を入力できるオープンエンドポイントからのものであると仮定します)。

これにより、カスタムパスをに追加できますfileName

もちろん、これはすべてのファイルが事前定義されたディレクトリにある場合にのみ機能します。

ただし、これは、ユーザーがアクセスできないファイルの削除を処理するためには何もしませんファイルがそのディレクトリ内の別のユーザーに属している場合、それが当てはまるかどうかを確認するためのチェックはありません(ただし、すべてのユーザーがこれらのファイルを削除する権限を持っている場合は問題ありません)。

また、次のように、クラスのCombineメソッドPathを使用してパスを結合することもできます。

string path = Server.MapPath(@"~\docs\custFiles\")
path = Path.Combine(path, year);
path = Path.Combine(path, cNum);
path = Path.Combine(path, fileName);

.NET 4.0以降を使用している場合は、パスの一部をパラメーター配列として受け取るメソッドのオーバーロードをCombine使用できます。

string path = Path.Combine(
    Server.MapPath(@"~\docs\custFiles\"),
    year, cNum, fileName);

最後に、Shaiが指摘しているように、可能であれば(完全なソリューションとして)、これをさらに安全にするには、ファイルシステムレベルでアクセス許可を有効にする必要があります。

ユーザーになりすましている場合、または制限されたユーザーアカウントを使用してすべての要求を処理している場合は、そのユーザーに ~\docs\custFiles\ディレクトリ(および任意のサブディレクトリ)のみへのアクセスを許可する必要があります。

そのディレクトリより上のものは、ユーザーアカウントがアクセスできないようにする必要があります。

于 2013-01-03T18:36:05.690 に答える
1

ファイル名とディレクトリ名が有効なファイル名であるかどうかを確認することをお勧めします。次の文字配列と照合して確認してください。

Path.GetInvalidFileNameChars

編集:

また、おそらく次のように年と番号も検証する必要があります。

bool valid = int.TryParse(num, out temp);

于 2013-01-03T18:40:08.490 に答える
1

ファイル システムに組み込まれているセキュリティを使用して、ユーザーが不要なディレクトリ内のファイルを削除できないようにすることも検討してください。1 つのディレクトリのみでファイルを削除する権限を持つ特定のユーザーの下で Web アプリが実行されている場合、ユーザーが何をしようとしても、アプリには削除を実行する権限がありません。

さらに、これにより、アプリを再デプロイすることなく、メンテナンス (つまり、新しいディレクトリの追加) が非常に簡単になります。

その後、無効なアクセス試行にアクセスしようとする試みをキャッチし、必要に応じて何かを実行できます。

[WebMethod(EnableSession = true, 
    Description = "Method for deleting files uploaded by customers")]
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public Boolean deleteCustFiles(string cNum, string year, string fileName)
{
    try
    {
        if (String.IsNullOrEmpty(cNum) || String.IsNullOrEmpty(year) ||
            String.IsNullOrEmpty(fileName))
            throw new Exception();
        string path = 
            Server.MapPath(@"~\docs\custFiles\" + year + @"\" + cNum + 
                @"\" + fileName);
        File.Delete(path);
    }
    catch (System.Security.SecurityException e)
    {
        throw new Exception("Unauthorized attempt to delete file");
    }
    catch
    {
        throw new Exception("Unable to delete file");
    }

    return true;
}
于 2013-01-03T18:40:46.357 に答える