書籍『Ajaxセキュリティ』に関する残念なお知らせ
残念だと思う主要な理由は,脆弱性への対策が十分に示されていないことだ。Ajaxであってもインジェクション系脆弱性が発生する可能性があること,むしろ従来型のWebアプリケーションよりもその可能性が広がることは説明されているが,肝心の対策が不十分だ。
本書第四章の後半には,対策として入力検査(バリデーション)が示されている。
- 4.6 適切な入力検査
- 4.7 リッチなユーザ入力のバリデーション
しかし,入力検証だけでは,任意の文字入力を許す場合の対策はできない。入力検証は、アプリケーション仕様に基づいて検証するのであるから,仕様として「<」,「>」,「"」,「'」,「/」などの入力を許可する場合には,検証ではじくわけにはいかないからだ。
現実問題として,英米人の名前にはアポストロフィ「'」がつく場合がある(例えばM'Intosh)。これら記号の処理をどうせよと説明しているのだろうかと思って本書を読み進めたところ,ちょうどそのテーマの説明があった(P113)。
しばしば問題となるのは,アポストロフィの取り扱いです。英語圏のユーザにとって,氏名や固有名詞などでアポストロフィを入力できる方が便利です。しかし、ユーザの入力にアポストロフィの仕様を許可する場合,インジェクション攻撃を防ぐにはどうすればよいでしょうか。
解決策は,ホワイトリストパターンの改良を続けることです。ユーザの姓として,O'Brienなら有効な値でしょうが,'SELECT * FROM tblCreditCardsはまず違うでしょう。単語の数(正規表現の用語では,空白文字で区切られた,英数字からならるグループの数)を制限することも検討して下さい。使用が許されるアポストロフィの個数を制限するのも,1つの方法です。複数のアポストロフィが含まれる名前など,まずありえないからです
これに対して,訳註がついている。
訳註:名前のフィールドにはアポストロフィを1つだけ許可するとしても,それを保存するSQL文や表示するHTML/XMLではアポストロフィを正しくエスケープしなければ,Webアプリケーションとして機能しないのは当然である。しかし,後の章で説明する多層防御のうちの1レイヤとしてであれば,この入力検査も無意味なわけではない。
訳註の第1センテンスは極めて妥当な,というより当然の内容である。しかも,このエスケープがあれば,バリデーションがなくてもインジェクション対策になっているのだ。だとすれば,インジェクション対策の原則として,まずエスケープの方を説明すべきであるが,本書にはHTML/XML/JavaScript(JSON)/SQLなどのエスケープが説明されていないようだ。これでは,そもそも特殊記号を含む文字列の正しい処理ができない。
また,「解決策は,ホワイトリストパターンの改良を続けることです」という説明もおかしい。ホワイトリストの許容範囲を広げていくと,現実にはホワイトリストではなく,どんどん「グレーリスト」になってしまうのだ。その典型が,「使用が許されるアポストロフィの個数を制限する」という説明だ。SQLインジェクションはアポストロフィ(シングルクォート)1つで十分攻撃できる。現に,引用箇所の少し前に例示された「'SELECT * FROM tblCreditCards」は,アポストロフィは1つだけだ。筆者は自己矛盾を感じなかったのだろうか。
実際には,「アポストロフィ1つまでは許可する」というのはホワイトリストではない。「アポストロフィ2個以上が入った文字列は攻撃と見なす」というブラックリストを裏返しただけのことで,実質的にはブラックリストなのだ。ホワイトリストとブラックリストの区別がつかない「セキュリティ専門家」は,日本だけでなく,欧米にもいるようだ。
というわけで,本書は読むべき箇所がない訳ではないのだが,肝心なことが説明されていなくて役に立たないと思った。その前に読んだAjaxアプリケーション & WebセキュリティもAjaxのセキュリティに関しては散々な出来で,滅多に専門書を手放さない私も,Amazonマーケットプレイスで売ってしまった。
Ajaxは技術が急速に普及した一方で,セキュリティに関するまとまった解説が見あたらない。良書が少しでも早く発刊されることを切望する次第である。