、私はこの解決策を考え出した:
public static boolean isParent(File parent, File file) {
File f;
try {
parent = parent.getCanonicalFile();
f = file.getCanonicalFile();
} catch(IOException e) {
return false;
}
while(f != null) {
// equals() only works for paths that are normalized, hence the need for
// getCanonicalFile() above. "a" isn't equal to "./a", for example.
if(parent.equals(f)) {
return true;
}
f = f.getParentFile();
}
return false;
}
ので使用量は次のようになります。
File file = new File(folder, path);
if(! isParent(folder, file)) {
... deny access ...
}
上記のコードはあまり速くない可能性がありますが、他のすべてのソリューションにはセキュリティ上の問題があります。
/../|^../|/..$
を削除できましたが、Windowsでは動作しません。 Windowsの場合、パターンはより複雑になるとJavaは、Windows上のファイルセパレータとして/
を受け入れることを忘れないでください、それはdoesnのため、
また、パスa/../b/c
が有効である(はい、C:/Windows/
が有効であるとは同じC:\Windows\
手段として)境界を壊していないので、相対的な動きを取り除くだけでは十分ではありません。
getCanonicalPath()
を使用して2つの文字列を作成し、parent
のパスがfile
の接頭辞であることを確認してください。しかし、私は、親のパスの後の文字がファイルセパレータであることを確認する必要があります(上記のFile.SEPARATOR
が十分でない理由を参照)。
あなたはJavaでそれを必要とする理由セキュリティのこの種は、ファイルのパーミッションによって行われますか? – Dima
_blackフォルダlist_を残して、パスがリストにないことを確認するだけで十分ですか? – Michael
いくつかの興味深いファイルはサーバーでは読み取り可能でなければならない場合があるため、サーバー上で実行されているアプリケーションでは読み取れない可能性があります。 '/ etc/passwd'を読むこと自体はセキュリティ上の問題ではありません。何も損害を与えませんが、その情報から学んだ情報はシステムを攻撃しやすくなります。 –