Unicode 5.2 より前のいくつかのバージョンでは、適合性条件 C7 において、非文字コードポイント(noncharacter code points)を削除することを認めている。たとえば、Unicode 5.1 の適合性条件 C7 には以下のように記述されている[Unicode 2007]。
C7. valid な文字列の解釈を変えないようにするためには、プロセスは正準等価な文字列への変換および非文字コードポイントの削除以外の変換を行ってはならない。
Unicode Technical Report #36 「Unicode Security Considerations」[Davis 2008b] の セクション3.5 "非文字コードポイントの削除" には以下のように記述されている。
C7 の古いバージョンで認められていたような、暗黙のうちに文字を削除する動作(置き換えでなく)はセキュリティ上の問題となりうる。たとえば以下のような場合が考えられる: ゲートウェイが "delete" という文字列が含まれているデータを拒否するように設定されているとする。データのなかに "deXlete" (ここで X は非文字コードを表しているとする) という文字列が含まれていても、ゲートウェイのチェックにはかからずに通過する。しかし、この後の処理の中でXが暗黙のうちに削除されてしまうと、その結果は "delete" という文字列になり、ゲートウェイによるチェックを回避されてしまったことになる。
非文字コードポイントの削除や置き換えを含む文字列の変更はすべて、文字列の検証前に行わなければならない。
違反コード
以下の違反コードは、正当なASCII文字だけを受け付け、非ASCII文字を削除している。また、<script> タグの存在もチェックしている。
入力値検査は非ASCII文字の削除の前に行われている。そのため、攻撃者はコードに与える入力の中で <script> タグを偽装して入力値検査をすりぬけることが可能である。
// "\uFEFF" は非文字コードポイントの一つ String s = "<scr" + "\uFEFF" + "ipt>"; s = Normalizer.normalize(s, Form.NFKC); // 入力値検査 Pattern pattern = Pattern.compile("<script>"); Matcher matcher = pattern.matcher(s); if (matcher.find()) { System.out.println("Found black listed tag"); } else { // ... } // 非ASCII文字の削除 s = s.replaceAll("[^\\p{ASCII}]", ""); // s には "<script>" が含まれている
適合コード
以下の適合コードでは、認識できない文字や表示できない文字を Unicode 文字 \uFFFD に置き換えている。\uFFFD は、アプリケーションが認識できない文字と入れ換えるために予約された文字である。また、この入れ換えは <script> の存在チェック等あらゆる無害化処理の前に行われる。こうすることで、偽装した入力による検査回避を防ぐことができる。
String s = "<scr" + "\uFEFF" + "ipt>"; s = Normalizer.normalize(s, Form.NFKC); // 無用な文字はすべて U+FFFD に置換 s = s.replaceAll("[^\\p{ASCII}]", "\uFFFD"); Pattern pattern = Pattern.compile("<script>"); Matcher matcher = pattern.matcher(s); if (matcher.find()) { System.out.println("Found blacklisted tag"); } else { // ... }
Unicode Technical Report #36 「Unicode Security Considerations」[Davis 2008b] によれば、「U+FFFD はまさにこのような用途のために予約された文字であり、通常はなんの問題も起こさない。プログラミング言語の文法上なんらかの意味を持つ文字であるとか、構造化データにおいて特殊な意味を持つ文字であるといったことがなく、単純に文字列のパーズ処理を失敗させるだけだからである。ただし、出力先の文字セットが Unicode でない場合、これに相当する文字は存在しないかもしれない」
リスク評価
非文字コードポイントを削除する前に文字列の検証を行っている場合、細工された文字列によって検証を回避される可能性がある。
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
IDS11-J |
高 |
中 |
中 |
P12 |
L1 |
関連ガイドライン
CWE-182. Collapse of data into unsafe value |
参考文献
[API 2006] |
|
[Davis 2008b] |
3.5, Deletion of Noncharacters |
[Weber 2009] |
Handling the Unexpected: Character-deletion |
[Unicode 2007] |
|
[Unicode 2011] |
|
翻訳元
これは以下のページを翻訳したものです。
IDS11-J. Eliminate noncharacter code points before validation (revision 90)