IDS05-J. ファイル名やファイルパスにはASCII文字セットの一部の文字のみを使用する
ファイル名やパス名にある種の文字が含まれていると、思いがけない挙動を招くことがあり、場合によっては脆弱性に結びつくこともある。ファイル名やパス名を作成する際に含まれていると問題になりかねない文字や文字列のパターンを以下に挙げる。
- 文字列先頭のダッシュ文字: ファイル名を引数にプログラムが呼び出されるとき、ファイル名の先頭がダッシュ文字だと問題が発生する可能性がある。先頭のダッシュ文字は文字列がプログラムのオプションであると解釈される可能性があるからだ。
- 改行、復帰、エスケープなどの制御文字: ファイル名やログに出力する文字列に制御文字が含まれていると、予期せぬ挙動を引き起こす可能性がある。
- 空白文字: 空白文字を含むファイル名を二重引用符でくくっていない場合、スクリプトの中で問題になる。
- 無効な文字エンコーディング: 文字エンコーディングはファイル名やパス名の検証を難しくする場合がある。(「IDS11-J. 文字列の変更はすべて検査の前に行う」を参照。)
- 名前空間区切り文字 (Name-space separation characters): ファイル名やパス名に名前空間区切り文字が含まれていると、予期せぬ挙動を招く可能性がある。
- コマンドインタプリタ、スクリプト、パーザ: コマンドインタプリタ、シェル、コマンドパーザにとって、ある種の文字は特定の意味を持つ場合がある。そのような文字をの使用は避けるべきである。
MS-DOS の影響もあり、xxxxxxxx.xxx というパターンのファイル名(xは英数字一文字を表す)は、こんにちのシステムでは正しく扱えると考えてよいだろう。ファイル名の大文字小文字を区別するプラットフォームもあれば、そうでないプラットフォームもある。VU#439395 は、大文字小文字の問題を正しく扱わなかったために発生したC言語における脆弱性の例である[VU#439395]。
このルールは「IDS00-J. SQL インジェクションを防ぐ」の具体例になっている。
違反コード
以下の違反コード例では、ファイル名の一部に安全に取り扱えない文字が含まれている。
File f = new File("A\uD8AB"); OutputStream out = new FileOutputStream(f);
安全でない文字をどう扱うかはプラットフォームに任されている。たとえば Ubuntu Linux では、このファイル名は以下のようなものとして扱われる。
A?
適合コード
前述のように、ファイル名には ASCII 文字集合のなかで安全に扱われることが明確な文字種のみを使うべきである。
File f = new File("name.ext"); OutputStream out = new FileOutputStream(f);
違反コード
以下の違反コード例では、ユーザからの入力を無害化せずにファイル名として使っている。
public static void main(String[] args) throws Exception { if (args.length < 1) { // エラー処理 } File f = new File(args[0]); OutputStream out = new FileOutputStream(f); // ... }
このコードでは、ファイル名の中に問題を引き起こす文字が含まれていないか検査していない。ファイルを作成したりファイル名を変更するプログラムにこのコードが含まれ、ファイルが後にスクリプトなどの自動化されたプロセスに利用されるということを攻撃者に知られると、後の処理で問題を引き起こすような文字列を入力されてしまうかもしれない。
適合コード
以下の適合コードでは、ホワイトリストを使って安全でないファイル名を排除している。
public static void main(String[] args) throws Exception { if (args.length < 1) { // エラー処理 } String filename = args[0]; Pattern pattern = Pattern.compile("[^A-Za-z0-9%&+,.:=_]"); Matcher matcher = pattern.matcher(filename); if (matcher.find()) { // ファイル名に無効な文字が含まれている。エラー処理。 } File f = new File(filename); OutputStream out = new FileOutputStream(f); // ... }
信頼できない入力から得られたファイル名は無害化し、安全な文字のみが含まれることを保証しなくてはならない。
リスク評価
ASCII 文字セットのなかの安全な文字だけを使用しないと、データの誤解釈につながる可能性がある。
ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
IDS05-J | 中 | 低 | 中 | P4 | L3 |
関連ガイドライン
CERT C Secure Coding Standard | MSC09-C. Character Encoding - Use Subset of ASCII for Safety |
CERT C++ Secure Coding Standard | MSC09-CPP. Character Encoding - Use Subset of ASCII for Safety |
ISO/IEC TR 24772:2010 | Choice of filenames and other external identifiers [AJN] |
MITRE CWE | CWE-116. Improper encoding or escaping of output |
参考文献
ISO/IEC 646-1991 | ISO 7-bit coded character set for information interchange |
[Kuhn 2006] | UTF-8 and Unicode FAQ for UNIX/Linux |
[Wheeler 2003] | 5.4, File Names |
[VU#439395] |
翻訳元
これは以下のページを翻訳したものです。
IDS05-J. Use a subset of ASCII for file and path names (revision 53)