ServletContext.getRealPath の引数を検証する必要があるか

Servlet で仮想パスからファイルシステム上の絶対パスを得るときは、ServletContext.getRealPath(String path)メソッドを使う。メソッドの説明を読むと仮想パスを実際のパスに変換できなかった場合には null を返すようだし、Servlet が管理している範囲でしかファイルを読めないように思える。以下に、メソッドの説明を引用する。

Gets the real path corresponding to the given virtual path.

For example, if path is equal to /index.html, this method will return the absolute file path on the server’s filesystem to which a request of the form http://<host>:<port>/<contextPath>/index.html would be mapped, where <contextPath> corresponds to the context path of this ServletContext.

The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators.

Resources inside the /META-INF/resources directories of JAR files bundled in the application’s /WEB-INF/lib directory must be considered only if the container has unpacked them from their containing JAR file, in which case the path to the unpacked location must be returned.

This method returns null if the servlet container is unable to translate the given virtual path to a real path.

しかし、実際には任意の物理パスが戻ってくることがあるようだ。Windows + Tomcat 6.0.35 の環境で試してみた。

ServletContext servletContext; // どこかから渡された ServletContext
String[] list = new File(servletContext.getRealPath("../../../../")).list();
for(String s: list) {
	System.err.println(s);
}

結果は以下の通りだ。

$RECYCLE.BIN
workspace
workspace-android

ServletContext.getRealPath(String path)メソッドの引数に、ユーザー入力値を与える場合は、入力チェックで予期していない文字が入っていないことをチェックする必要がある。


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.