IDS01-J. 文字列は検査する前に正規化する
信頼できない入力文字列を受け取るアプリケーションの多くは、文字列に含まれる文字データに基づいた入力値のフィルタや検査メカニズムを採用している。たとえば、クロスサイトスクリプティング(XSS)の脆弱性を回避する戦略のひとつとして、<script>
タグの入力を禁止するという方法がある。このようなブラックリスト方式のメカニズムは、入力値を完全に無害化することはできないが、セキュリティ上の戦略の一部としては有用である。
Javaにおける文字情報は Unicode標準に基づく。Java SEの最新3リリースで対応しているUnicodeのバージョンを以下の表に示す。
Java Version | Unicode Version |
---|---|
Java SE 6 | Unicode Standard, version 4.0 [Unicode 2003] |
Java SE 7 | Unicode Standard, version 6.0.0 [Unicode 2011] |
Java SE 8 | Unicode Standard, version 6.2.0 [Unicode 2012] |
信頼できない入力を受け取るアプリケーションは、入力値を検査する前に正規化するべきである。Unicodeでは同じ文字列が複数の異なる表現を取り得るため、正規化が重要だ。Unicode Standard [Davis 2008] Annex 15は、Unicodeの正規化形式(Normalization Form)について以下のように規定している。
処理系が文字列を正規化形式で保持する場合、等価な文字列は一意のバイナリ表現を持つことが保証される。
違反コード
以下の違反コードでは、文字列を正規化する前に検査を試みている。
// String s はユーザに制御されているかもしれない
// NFKC では \uFE64 は < に、\uFE65 は > に正規化される
String s = "\uFE64" + "script" + "\uFE65";
// 検査する
Pattern pattern = Pattern.compile("[<>]"); // 山括弧かどうかのチェック
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
// ブラックリストに登録されたタグを見つけた場合の処理
throw new IllegalStateException();
} else {
// ...
}
// 正規化する
s = Normalizer.normalize(s, Form.NFKC);
検査ロジックの時点で文字列が正規化されておらず、<script>
タグは検出されない。そのため、システムは不正な入力を受け付けてしまう。
適合コード
以下の適合コードでは、文字列を検査する前に正規化を行っている。山括弧に相当する文字列表現は、正規化された山括弧に変換される。その結果、入力値検査は悪意のある入力を正しく検出することができ、IllegalStateException
例外をスローする。
String s = "\uFE64" + "script" + "\uFE65";
// 文字列を正規化する
s = Normalizer.normalize(s, Form.NFKC);
// 文字列を検査する
Pattern pattern = Pattern.compile("[<>]");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
// ブラックリストに登録されているタグを発見した
throw new IllegalStateException();
} else {
// ...
}
リスク評価
入力値を正規化する前に検査すると、攻撃者は入力値フィルタや他のセキュリティメカニズムを回避できるかもしれない。結果として任意のコード実行につながる恐れがある。
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
IDS01-J |
高 |
中 |
中 |
P12 |
L1 |
自動検出
ツール | バージョン | チェッカー | 説明 |
---|---|---|---|
The Checker Framework |
2.1.3 |
Tainting Checker | Trust and security errors (see Chapter 8) |
Fortify | 1.0 |
Process_Control |
Implemented |
関連ガイドライン
ISO/IEC TR 24772:2013 |
Cross-site Scripting [XYT] |
CWE-289, Authentication bypass by alternate name |
実装の詳細 (Android)
Androidアプリも、外部から文字列データを受け取って正規化することがある。
参考文献
[API 2006] |
Java Platform, Standard Edition 6 API Specification |
[Davis 2008] |
|
[Weber 2009] |
Exploiting Unicode-enabled Software |
翻訳元
これは以下のページを翻訳したものです。
IDS01-J. Normalize strings before validating them (revision 123)