Java で一時ファイルを生成するときは、File.createTempFile(String, String) メソッドを使うことが多い。ディレクトリを指定したい場合は、File.createTempFile(String, String, File) メソッドを使用する。createTempFile メソッドはファイルを生成するだけで、削除は行わない。ファイルを半自動的に削除するためには、File オブジェクトに対して deleteOnExit() メソッドを使用する必要がある。
セキュリティ的に気になるのは、プレフィックスとして利用する第一引数だ。第一引数は、ファイル名を生成するために使用されるプレフィックス(接頭辞文字列)で、3 文字以上の長さが必要とされている。第二引数は、接尾辞で null の場合は “.tmp” を使用する。
プレフィックスは任意の文字列を指定できるが、3文字未満だと IllegalArgumentException の例外を通知する。通常は、以下のように呼び出す。
File f1 = File.createTempFile("tempTest", null);
Windows 7の環境で実行してみると、「C:\Users\<ユーザー名>\AppData\Local\Temp\tempTest151634446871062311.tmp」というファイル名になった。ここまでは何の問題もない。
ちょっと意地悪をして、以下のような呼び出しに変更してみる。
File f2 = File.createTempFile(".." + File.separator + ".." + File.separator + ".." + File.separator + "tempTest", null);
先ほどと同様に Windows 7の環境で実行してみると「C:\Users\<ユーザー名>\tempTest4738948300465451623.tmp」というファイル名になった。できれば「C:\Users\<ユーザー名>\AppData\Local\Temp\」以下にファイルを生成してほしかったが、第一引数か生成したファイルのパスをチェックする必要があるので行っていないようだ。念のため、第三引数でディレクトリを指定してみたが、動きは同じだった。
createTempFile(String, String) メソッドの第一引数、ファイル名のプレフィックスにユーザー入力値を渡すケースは少ないので危険はほとんどないが、気になったので実験してみた。ついでなので、第二引数の接尾辞も試してみた。
File f3 = File.createTempFile("tempTest", "test" + File.separator, new File("C:/temp"));
の結果は、「C:\temp\tempTest3468039393432029533test」となるが、
File f4 = File.createTempFile("tempTest", "test" + File.separator + ".tmp", new File("C:/temp"));
の結果は、「Exception in thread “main” java.io.IOException: 指定されたパスが見つかりません。」となりファイルが生成されなかった。