他の回答を読んだ後、私はこの解決策を思いつきました:
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 のファイル区切りとして受け入れることを忘れないでください(はい、C:/Windows/
有効であり、 と同じ意味ですC:\Windows\
) 。
また、パスa/../b/c
は境界を壊さないので有効なので、相対的な動きを取り除くだけでは十分ではありません。
を使用して 2 つの文字列を作成し、パスが のプレフィックスであるgetCanonicalPath()
ことを確認できます。ただし、親パスの後の文字がファイル区切り文字であることを確認する必要があります (上記の理由を参照してください)。parent
file
File.SEPARATOR