エスケープする文字
何処とはいいませんけど、あるサイトの脆弱性が非常に気になる今日この頃。そのサイトはPHPを使っていて、いろんなところにフォーム*1がある。そして、ほとんどすべてのフォームでいわゆる「サニタイジング」を行っていない(!)
文字数制限が入っている部分もあって、さすがに全角10文字だと何もできない*2けど、文字数制限なしの部分も数ヶ所発見・・・
で、これはやばいと思ってちょっと前から管理者に問い合わせてるんだけど、全く音沙汰なしときた。さて、このサイトが攻撃されなきゃいいけど・・・
で、話はエスケープする文字についてなんだけど、このサイトを作った人は、文字列だけをエスケープすればいいと思ってるようで、シングルコーテーションとダブルコーテーションだけはエスケープしていた。
なぜそう思ったのかはおそらく、「いくらJavaScript等が使えたって、文字列が使えないんじゃぁ攻撃用のスクリプトなんてかけないだろう。」と、こんな感じじゃなかろうか?
まぁ確かに、どこか別のページに飛ばすにしたって、リンク先の文字列が必要なわけで、その文字列が使えないんじゃぁまともなスクリプトは書けそうにない・・・って、ほんとか!?
もちろんそんなことはない。JavaScriptは文字コードから文字列を得るメソッド*3が存在する。
これを使えば、文字コードさえわかれば任意の文字列をプログラム中に埋め込むことができる。
たとえばこんな風にやるわけだ。
alert(String.fromCharCode(33030
,24369
,24615
));
実行してみる
これで「脆弱性」と書かれたアラートが出たはずだ。このスクリプトには文字列は出てこない。
さて、でも文字コードなんて調べるのが面倒だ、というかもしれない。まぁ、いちいち調べるのはさすがに骨が折れるので、これも簡単なスクリプトを作ってしまう(あれ?攻撃側に傾いてる?)。
function
convert(form) {var
result =""
; result +="String.fromCharCode("
;var
str = form.origin.value;for
(var
i =0
; i < str.length; i++) { result += str.charCodeAt(i);if
(i != str.length-1
) result +=","
; } result +=")"
; document.getElementById("result"
).innerText = result; }
これをちょこちょこっとHTML*4に埋め込んだのが下のリンク先。
実行してみる
これで任意の文字列をスクリプト内に埋め込める!って・・・あれれ?
まぁこんな感じに、ダブルコーテーションやシングルコーテーションだけをエスケープしたところで、JavaScriptの前にはあまり意味はないことが分かって頂けたと思う。scriptタグ等の使用を禁止するなり、<や>等をエスケープするなり、きちんと対策をとらないといけない。もちろん、これらはクライアントサイドで防ぐのではなく、サーバサイドで防がなければ意味はないが・・・まぁ、この理由は分かるでしょう*5。
ちなみにこれらのスクリプトを使用したことによる被害等の責任は取りませんよ、もちろん。