を使用Path.normalize()
して、パスから ".." 要素 (およびその前の要素) を取り除くことができます。たとえば、"a/b/../c" を "a/c" に変換します。パスの先頭にある「..」は削除されないことに注意してください。削除する前のディレクトリ コンポーネントがないためです。したがって、別のパスを追加する場合は、最初にそれを行い、次に結果を正規化します。
Path.startsWith(Path)
あるパスが別のパスの子孫であるかどうかを確認するためにも使用できます。当然のことながら、Path.isAbsolute()
パスが絶対パスか相対パスかがわかります。
API に入ってくる信頼できないパスを処理する方法は次のとおりです。
/**
* Resolves an untrusted user-specified path against the API's base directory.
* Paths that try to escape the base directory are rejected.
*
* @param baseDirPath the absolute path of the base directory that all
user-specified paths should be within
* @param userPath the untrusted path provided by the API user, expected to be
relative to {@code baseDirPath}
*/
public Path resolvePath(final Path baseDirPath, final Path userPath) {
if (!baseDirPath.isAbsolute()) {
throw new IllegalArgumentException("Base path must be absolute");
}
if (userPath.isAbsolute()) {
throw new IllegalArgumentException("User path must be relative");
}
// Join the two paths together, then normalize so that any ".." elements
// in the userPath can remove parts of baseDirPath.
// (e.g. "/foo/bar/baz" + "../attack" -> "/foo/bar/attack")
final Path resolvedPath = baseDirPath.resolve(userPath).normalize();
// Make sure the resulting path is still within the required directory.
// (In the example above, "/foo/bar/attack" is not.)
if (!resolvedPath.startsWith(baseDirPath)) {
throw new IllegalArgumentException("User path escapes the base path");
}
return resolvedPath;
}