質問

信頼する rootPath と、信頼しない relativePath があります。結果が rootPath の下にあること、およびユーザーが .. を使用して開始を戻すことができないように、それらを結合したいポイント。次のようなものを許可する相対パスをします hello \ .. \ world == world

役に立ちましたか?

解決

System.IO.Path.GetFullPath

展開するには、Path.Combineを使用し、結果に対してGetFullPathを呼び出し、その結果がrootPathで始まることを確認します。

ハードリンクからは保護されませんが、二重ドットなどの単純なものをキャッチする必要があります。

上記のコード:

string Resolve(string fileName)
{
    string root = FileRoot();
    string ret = Path.GetFullPath(Path.Combine(root, fileName));
    if (ret.StartsWith(root.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar)) return ret;
    throw new ArgumentException("path resolved to out of accesable directroy");
}

他のヒント

Path.GetFullPath()を呼び出して、信頼できる rootPath で始まるかどうかを確認できます。妄想する傾向がある場合は、 rootPath がルート化されていることも確認してください。

public Boolean IsPathSafe(String rootPath, String relativePath)
{
  return rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
    Path.IsPathRooted(rootPath) &&
    Patch.Combine(rootPath, relativePath).GetFullPath().StartsWith(rootPath);
}

最初のテストの説明については、テクノフィルの答えに関するAlex Martelliのコメントを参照してください。

できることの1つは、バックスラッシュ( \ )と二重ドット( .. )の数を数えることです。ドットはバックスラッシュの数よりも小さいです。フォルダ構造内の rootPath の上に移動するには、少なくとも二重ドットと同じ数のバックスラッシュが必要です。したがって、少なくとも relativePath のみを許可する場合は、もう1つバックスラッシュを使用すると、安全になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top