[PR]小規模ECサイトに最適なWAF、SiteGuard Lite

徳丸浩の日記


2007年08月29日 TwitterのXSS対策は変だ

_ Twitterのクロスサイト・スクリプティング(XSS)対策は変だ

Twitterが流行している。私もヘビーユーザとは言えないものの、結構愛用している(http://twitter.com/ockeghem)。このTwitterのXSS対策が変だなと思う事象があったので報告する。

あらかじめお断りしておくが、TwitterにXSS脆弱性がある(実際にはあったようだが)という報告ではなく、対策の方法がおかしいという報告である。
まずは、どうも変だと思うようになった事例を紹介する。

事例1 モバイル版の二重エスケイプ

私は主に、通勤などの移動中に、W-Zero3で閲覧・書き込みしている。モバイル版(http://m.twitter.com/)を主に利用しているが、「<」などの記号が二重にエスケープされていることに気がついた。

twitter.comでの表示
画像の説明



m.twitter.comでの表示
画像の説明




事例2 検索画面が変
 「Find&Invite」という機能でお友達候補を検索できるのだが、この機能が変だ。「lt」という単語で検索すると、「<」がヒットする。検索結果の例を下図に示す(私のプロファイル)。

画像の説明



しかしこの表示は実はおかしくて、私のプロファイルは実際には下図のように設定されているのだ。

画像の説明



すなわち、ltで検索すると、「<」がヒットされていることになる。そして、ネタばれのように、検索結果表示では「<」の部分が「&lt;」と表示される。


3.事例3 文字数制限が変

Twitterの氏名欄(Full Name)は20文字までという制限になっているが、「<」などの文字を使うと、より少ない文字しか入らない。ここで、「<1234567890123>」という15文字の名前を入れてみる。
すると、下図のように、「<1234567890123&gt」というように文字列が化けてしまう。
画像の説明


おそらく、内部的には「&lt;1234567890123&gt;」と格納しようとしたものの、これだと21文字になるので、末尾のセミコロンが削除されてしまったのだろう。

結論:Twitterは、HTMLエスケープされた状態で情報を保存している

もういいだろう。ソースを確認したわけではないが、これだけ状況証拠があれば十分だ。TwitterはHTMLエスケープされた文字列をDBに保存していることは間違いない。
しかし、この方法は間違っている。HTML表示する直前にHTMLエスケープするという原則に反しているからだが、その結果として、上記に見るような悪影響が出ている。設計ミスというほかないだろう。

さて、文字列をHTMLエスケープされた状態で保存したために悪影響が出ていることは報告の通りだが、この方法のメリットはあるだろうか?一つ思いつくことは、DB格納の段階でまとめてHTMLエスケープすることにより、HTMLのエスケープもれによるXSS脆弱性が発生することを防ぎたかったのかもしれない。
しかしながら、この方法ではかえってXSS脆弱性を招きやすいと私は思う。DBの値はエスケープ済みだが、画面からの入力値(などDB以外の値)はエスケープされていない。両者が混在することによって、エスケープすべきものとしなくてよいものの区別が煩雑になり、結果としてXSS脆弱性が発生しやすくなると思われる。現実問題、TwitterではXSS脆弱性が報告されているようである。

TwitterのXSS対策はサニタイズではなくエスケープという正しい方法を使っているが、エスケープする場所がよくなかった。Twitterそのものの改良も期待するが、読者が抱えるプロジェクトのセキュリティ対策の参考になれば幸いである。

追記(2007/08/29 19:30)

<と>以外の記号について調べると、「&」、「"」、「'」については何もエスケープされていないことが分かった。ひどい仕様だ。
このため、画面から「&lt;」と入力すると、これらの記号はそのままDBに入り、そのまま表示されるので、「<」に文字化けする。その他、XSSになりそうな爆弾もありそうだ。
twitter.comのようなアドホックなXSS対策は見たことがなく、ある意味興味深い。

本日のツッコミ(全2件) [ツッコミを入れる]

_ rna [& のエスケープですが、HTMLの文字参照になっている場合はエスケープしないという仕様のようです。&foo; とかす..]

_ 徳丸浩 [rnaさん、ツッコミありがとうございます。&のエスケープの件、ありがとうございます。そういうことですか。しかし、一貫..]


2007年08月21日 アンチ「サニタイびんぷ」

_ 画像版サニタイズ言うな(2)

 前回のエントリーの後、mod_imagefightのコマンドライン版を作ったりして、検証してみました。まだ検証途中ですが、今回はBMP形式についてのアンチmod_imagefightについて紹介します。
 まず、BMP形式のヘッダは以下のようになります(カッコ内はバイト数)。

0000:MARK(2) ='BM'
0002:ファイルサイズ(4)
0006:予約1(2) =0
0008:予約2(2) =0
000A:ビットマップ開始位置(4)
000E:ヘッダサイズ(4) =0x28
0012:イメージ横幅(4)
0016:イメージ高さ(4)
001A:プレーン数(2) =1
001C:ピクセルあたりのビット数(2) 1,4,8,24
001E:圧縮形式(4) =0,1
0022:圧縮後のイメージサイズ
0026:水平解像度(4)
002A:垂直解像度(4)
002E:使用色数(4)
0032:重要な色数(4)
0036:カラーパレット BGR0 の繰り返し(8ビット以下の場合のみ)
XXXX:サニタイジング文字列 ※注
ZZZZ:ビットマップ
 上記で、サニタイジング文字列(※注)については、mod_imagefightが挿入する部分です。BMPは上記のように単純な形式のため、カラーパレットの後にサニタイジング文字列が来ています。本来はカラーパレットの前にこれを起きたいのですが、BMPの構造上、それは不可能と思われます。id:takesakoさんも相当苦労されたのではないかと思います。
 このため、カラーパレット(を含むヘッダ部分)については、サニタイジング文字列以外の方法で対処が必要となります。BMPの場合、カラーパレットは最大1024バイト確保されるので、とくにカラーパレットに対する対策は重要です。
 mod_imagefightで採用されている方法は次の二点です。
 まず、通常カラーパレットは24ビット(3バイト)で表現されますが、BMP形式の場合は、ワード境界に合わせたのか、カラーパレットは一色あたり4バイト使います。4バイト目は予約領域であり、0が入ることになっていますが、ここに攻撃用の文字列を挿入することは可能です。
 このため、mod_imagefightでは、この4バイト目の領域を強制的に0にリセットしています。
 次に、RGB値に対しては、たまたま'<'や'>'の値になった場合は、値を一つ増やすことによって'<'や'>'の出現を防止しています(関数sanitize_RGB)。ここは、mod_imagefightでもっとも苦しいなぁと感じるところで、微妙に色が変化することになりますが、実用上はそれほど問題にはならないのでしょう。きっと。
 さて、この前提で、mod_imagefightに対する攻撃手法を検討します。
 BMPは単純な構造であり、またヘッダの多くはmod_imagefightによる正規化により値をあるべき値に変更されています。攻撃文字列のほとんどは、カラーパレットに置くしかないでしょう。しかし、この部分には、肝心の'<'と'>'を使うことができません。
 唯一、mod_imagefightが見逃している領域として、「002E:使用色数(4)」があります。ここにタグを書くことにしましょう。といっても、'<'は一つ書くのがせいぜいなので、JavaScriptはイベントハンドラの中に書くことにします。使用色数は4バイトしか使えないので、<IMG>を使うことにして、JavaScriptはonloadイベントとして記述します。
使用色数:<IMG
パレット: SRC="a.png" onload="alert('xss');" 
ただし、このままでは、カラーパレットに対する4バイト目のゼロクリアで、JavaScriptがズタズタに切り裂かれますので、3バイトずつに区切った上で、間に一文字入れておきます。以下では、区切りを「~」で表現していますが、ここはゼロクリアされるので、値は何でもかまいません。IEがヌル文字(値0の文字)を無視する性質を利用しています。
パレット: SR~C="~a.p~ng"~ on~loa~d="~ale~rt(~'xs~s')~;" 
 この状態で、mod_imagefightを通すと、以下のようになります。

図1:mod_imagefight後

 また、IEでこの画像を表示されると、以下のようにJavaScriptが起動されます。a.pngが存在することが必要ですが、置き場所は調整可能です。

  図2:攻撃例

 この攻撃への対策は簡単だと思いますので、id:takesakoさんが速攻で修正してくださることでしょう。イメージファイトはまだまだ続く・・・

PS.
 mod_imagefightにはGET32LEとかGET32BEというマクロが出てきます。LEとBEはそれぞれリトルエンディアンとビッグエンディアンを表すような気がしますが、名前と実体が逆になっているようです。ご確認を。

参考文献
T.Teradaの日記 - [セキュリティ]ImageFight2
葉っぱ日記 - Apacheに埋め込まれたイメージファイトと戦う文字コードな方法

追記

id:takesakoさんからはてなブックマークコメントを頂戴しました。
>ゼロじゃない別の文字でパディングする方法も検討してみます。
これは巧妙な方法ですね。カラーパレット中の予約領域をゼロでクリアしているために、却ってIEがゼロ(ヌル文字)を無視するという仕様を悪用されるわけで、意味のある文字を挿入したら、パレット領域に攻撃文字列を仕込むことは非常に困難になるでしょうね。
# どの文字だったら、攻撃が成立し得るかを考えることは、挑戦的なパズルではありますが。

今後の改良に期待します。


2007年08月07日 mod_imagefight考

_ 画像版サニタイズ言うな

しばらく前から、竹迫さんのイメージファイト(mod_imagefight)が、第10回セキュリティもみじセミナーなとで発表され話題になっていましたが、LL魂で発表されたプレゼン資料が公開されましたので、私もようやく内容を見させていただきました。

先日、PHPの攻撃コードが隠された画像ファイルが、大手ホスティングサイトで発見されたとの報道がなされました。GIF,PNG,JPEG,BMP形式の画像ファイルには、PHPのRFI攻撃で使用されるコードやJavaScriptのソースなどを埋め込むことができます。画像に埋め込まれた攻撃コードと戦う5つの方法について解説し、安全な画像アップローダの実装について考察します。

[TAKESAKO @ Yet another Cybozu Labs: LL魂お疲れ様でした[LLSpirit]より引用]


 公開されただけで61枚のプレゼン資料、4分間のライトニングトークですからいつもながら大変なものです。おそらく会場はやんやの喝采だったことと推察します。
 で、その中で提案されている mod_imagefight の手法ですが、画像によるXSSやRFI攻撃(Remote File Inclusion Attack)を防止するために、画像ファイル中に、PHPやJavaScriptを無効化するコード(テキスト)を挿入するものと理解しました。詳しくは、竹迫さんの素晴らしいプレゼン資料を参照ください。
 攻撃を予防するためのコードは、以下のようなものだそうです(C言語ソース形式、行番号は徳丸が付与)。
1:static const char antixss[] = 
2:    "\"'*/-->-->]]>\n\n"
3:    "<img src=# style=position:absolute;top:15;left:10;visibility:visible>"
4:    "<style>body{font-size:0;visibility:hidden}"
5:    "<plaintext style=display:none><?php die;?>";
 つまり、<style>や<plaintext> (PHPについては<?php die;?>)を挿入することにより、後続の<script>などを無効化しようというたくらみですね。  これはサニタイジングと呼ばれる手法の一種と考えられ、竹迫さんのプレゼン資料でも、サニタイGIF(sanitigif)とかサニタイピング(sanitipng)という造語を使って説明されている。このあたりのセンスはサスガですね。
 その一方で、同じプレゼン資料には、サニタイズ org という言及もみられます。これの意味するところは(プレゼンを聞いていないので)分かりませんが、想像するに、以下のどちらかではないでしょうか。

  • サニタイズという言葉を使うと某方面から批判が出る
  • サニタイズという手法は本質的にアドホックなもので、対応に限界がある


 ここでは後者について検討してみます。
 サニタイズに使用しているコードを見ると、スタイル指定<style>により<script>を無効化するとともに、念のため<plaintext>を併用して、万一<style>に対する対策がなされても、<plaintext>により<script>を無効にしているように見えます。
 しかし、この対策は、攻撃者側が</style>や</plaintext>を攻撃コードに含めることで対応できそうです。攻撃コードの例を以下に示します。

</plaintext></style><script>alert('xss');<script>
サニタイピング文字列+対抗文字列+XSS文字列
 私の環境ではすぐには mod_imagefight を試せそうにないので、代わりに竹迫さんのサニタイズ用テキストと攻撃コードを並べた文字列を埋め込んだ画像を作成してみました。右の画像がそうで、IEで画像のリンクをクリックすると、画像が表示され、alertによるダイアログが表示されます。画像が表示される理由は、サニタイピング文字列の3行目に<IMG src=#>があるためですね。
 えーっと、竹迫さんの実装では、サニタイピング文字列はコメント欄などを利用して埋め込むのだと思いますが、それは面倒だったので、全てパレットテーブルに押し込んでいます。本質的な差はないと思いますが、私の思い違いであればご指摘ください。
 この画像の16進ダンプを以下に示します。ハイライトしている部分がパレットの先頭部分で、サニタイピング文字列+対抗文字列+XSS文字列の順に並んでいます。

画像の先頭16進ダンプ

 というわけで、サニタイズという手法では、割合簡単に対抗策が取られてしまうのではないかという疑問を持ちました。
 僕のオオボケであればご指摘ください。
 テスト用に、サニタイピング文字列なしバージョンも用意しましたので、よろしければご利用ください。
対抗文字列+XSS文字列
さて、イメージファイトの改良についてですが、サニタイズ手法を使っている限り、攻撃者との「いたちごっこ」はつきまとうと思っています。画像のアップロード処理は、たとえばウィルスチェックが必要な場合もあるでしょうから元々重たい処理なのだと割り切って、もっと画像の中身をいじらないとしょうがないのではないかと思います。
 しかし、どうしてもサニタイズ的アプローチでやりたいのであれば、現状の<style>や<plaintext>ではなく、以下のようにJavaScriptで別のURIに遷移してしまったらどうでしょうか?
<script>location.href="/";</script>
 なんか毒をもって毒を制す風情がありますね(^-^;
 この方法のデメリットは、画像を直接(<IMG>を使わないで)表示できなくなることです。しかし、そういう応用は少ないのではないでしょうか?<IMG>による表示やダウンロードであれば問題ないと思います。

追記

 kazuhooku さんからはてブコメントをいただきました。「plaintext の閉じタグサポートしてる実装はあるんだろうか」ということですが、確かに主要なブラウザは</plaintext>を実装していませんね。ケータイのブラウザなどは対応していますが、なにせ今はIE固有の話題をしているわけで、失礼しました。なんとなく、(本当は終タグが必要だという意識もあって)書いてしまいました。
 すなわち、</plaintext>は書いても書かなくても意味は同じで、本質的に<style>の中はCDATAなので<plaintext>書いても効力ないこと、<style>の方は終タグが書けるので、攻撃側対応が容易というところが問題でした。<plaintext>を前にもって来るべきでしたね。
 まぁ、いずれにせよ私の結論は変わらなくて、こういうややこしいこともあるので、サニタイズ的な手法はあぶないなぁということです。

追記(2007/08/08)

作者のTAKESAKOさんから突っ込みをいただきました。<style>は、閉じていなかったとだけということで、XSS対策としては<plaintext>の方だということ。たしかに、プレゼン資料ではそうなっていたので、実装では<style>も足して「より強力に」したのかなぁと思ったのは私の勘違いでした。
試したわけではありませんが、この修正版を破るのは困難だと思いますので、現実的な対策としてはmod_imagefightは有効だと思います。ただ、この手法が、画像ファイルのXSS対策の決定版になるかどうかは、もう少し検証が必要だと思いますので、引き続き検討したいと思います。
ありがとうございました。

本日のツッコミ(全1件) [ツッコミを入れる]

_ TAKESAKO [元の防御コードの中でstyleの閉じタグが抜けていましたね。こちらのミス。 - 4: "<style>bod..]


2007年07月24日 書評のお稽古

_ 書評 - ウェブアプリケーションセキュリティ

金床氏の話題の新作「ウェブアプリケーションセキュリティ」が届いたので、ざっと目を通した。まだあまり紹介などが出ていないようなので、早い者勝ちで書評してみようと思う。

 本を手にとって最初に思うことは、その大部さである。いまどき、箱入り、ハードカバーで494ページもあり、ずしりとした手ごたえを感じる。日常のリファレンスや満員電車のお供にするのであれば、もっと軽薄短小であって欲しいと思うところだが、本書の場合そうではない。その理由は後述する。
 まず、本書の想定読者はどのような人だろうか。ウェプアプリケーションセキュリティの初心者でないことは確かだ。本書は内容にムラが多い。XSSや、CSRF、SQLインジェクション、セッション管理などについてはやたら詳しい代わりに、ディレクトリトラバーサル、コマンドインジェクション、ヘッダインジェクションについては「一応書いておかないとしょうがないな」と言わんばかりの薄っぺらさだ。この手の解説書の定番となってる強制ブラウジング、ディレクトリリスティングや、ファイルのダウンロードに伴う権限管理の問題などに至っては影も形もない。
 ディレクトリリスティングなどを説明しないのは、おそらくこれらがアプリケーションの問題ではなく、主にWebサーバーの設定の問題(アプリケーションではなく)だからであろう。また、アクセス権限管理は狭義のWebアプリケーション脆弱性パターンには属さず、機能要件として取り扱うべきものであるからだろう。そう説明できる。
 しかし、それにしてはSSLのMITM(Man In The Middle)攻撃については1章設けて説明している。これは通信の問題であって、アプリケーションの問題ではない。一見すると一貫性がないように見える。
 しかしながら実は、このようなムラや矛盾こそが本書の魅力の根源となっているのだ。要するに、筆者は書きたいことを書きたいように書いたのだ。筆者が力瘤を入れて書いた章は(世の中の基準ではなく)筆者が重要だと思っている内容であるし、筆者が書かなかった内容は(世の中では重要とされていても)筆者には興味がない内容であるのだろう。
 従って、本書はウェブアプリケーションセキュリティの網羅的な解説書ではない。
 上級者を目指す中級者にとっては、本書はちょうど良い手引きになるだろう。本書にはほとんど図表がないが、上級者たるもの「絵がない」くらいでめげてはいけない。図がない代わりに、文章は平明であるし、画面キャプチャやプログラムリストは適切に挿入されている。内容の高度さに比べて理解は容易である。
 上級者にとっては、二つの使い道がある。一つは、これまでネット上などで断片的に存在していた「高度な内容」をまとめ、読みやすい解説としたことである。そして、こちらの方が恐らく大切なのだろうが、金床節をたっぷりと味わうことである。典型的には、「2章データ処理の原則と指針」、「4章CSRF」、「6章SQLインジェクション」、「8章Guardian@JUMPERS.NET(筆者が開発したWAF)」、「16章DNSを使った攻撃」などである。
 WAFだと?そう、本書の特徴の一つがWAFに対する解説である。オープンソースのWAF開発者ならではの視点で、WAFの可能性と限界についてたっぷり解説してくれる。その視点は新鮮でかつ誠実である。そのような態度は、以下に引用するような部分で顕著である。

WAFを使用しブラックリスト方式のシグネチャマッチングによってXSS対策を行う場合、攻撃を完全に防ぐことは不可能である。【中略】望ましい対策として、パラメータごとにホワイトリスト式のチェックを行う方法が考えられるが、残念ながら多くのウェブアプリケーションではホワイトリストをきちんと定義することが難しい【中略】従って、WAFを使ってXSS攻撃を完璧に防ぐことは期待できない(P92~P94)。

 SQLインジェクションについても、WAFによる完全な対策はできないと説明する。 一方、CSRFについてはどうか。

クロスサイトスクリプティングやSQLインジェクションと異なり、CSRFはWAFで確実な対策を行うことが可能だ。ここではWAF(Guardian@JUMPERS.NET)を用いたCSRF対策について具体的に説明する(P119)。

 読者は、WAFを導入するとCSRF対策になるのだなと理解するであろう。
 しかし、これは正確な理解ではない。正確には、CSRF対策をWAFによって行うことが技術的に可能であること、Guardian@JUMPERS.NETではそれを実現していること、の二点だ。すべてのWAFがCSRF対策を確実に行えるわけではない。金床氏の文章は前述のように読みやすいのだが、一部に誤解を与えかねないような表現が散見される。
 引用した部分において誤解が生じた理由は明らかだ。この部分に至って、金床氏はWAFの開発者の視点で書いている。一般読者はWAFの利用者として読むであろう。そのギャップが誤解の元になるのだ。読者は、金床氏が今どの立場で解説しているかを意識するならば、誤解の余地はかなり減少するだろう。なんと言っても、元々は読みやすい文章なのだから。
 なお、そろそろ本書の対策方針については一言いっておかなければならない。これは、世の中で言われているガイドラインとは異なっている。「入力時に型やサイズチェック、出力時にエスケープ」という世の中で普及したガイドラインを「原則ではない」と言い切る。実は仔細に読んで行くと、そう過激な主張とも言えない場合もあるのだが、それは読者の楽しみにとっておくことにしよう。
 繰り返すが、本書は初心者向けの解説では決してなく、上級者が自身の楽しみに読むのが正しいと思う。であれば、箱入りであるとかハードカバーであることは決してデメリットではない。楽しい読み物として末永く楽しむべき本には、それにふさわしい体裁があるというものである。
 さらに言えば、本書は「二冊目」として購入すべき本である。では、一冊目としてはどれを購入すればよいか。もちろん、評者の本「Webアプリケーションのセキュリティ完全対策―不正アクセスや情報漏洩を防ぐ」を購入せよといいたいところだが、あいにく時間の経過とともに内容が少し古くなってしまった。現時点で「一冊目」としての絶対のお勧めはない。どなたか書いていただけないものだろうか。

本日のツッコミ(全5件) [ツッコミを入れる]

Before...

_ 金床 [sonodamさんがいいこと言った! …しかし改訂じゃなくてフルスクラッチでお願いします。]

_ 徳丸浩 [皆さん、ありがとうございます。本は書きたいのだけれど、今忙しくて・・・金床さんだって会社経営の傍ら14ヶ月(だっけ?..]

_ DOMO [はじめまして。現在Webアプリケーションの勉強をしていまして、徳丸さんの「Webアプリケーションのセキュリティ完全対..]


2007年07月17日 XSSテスト画像

_JavaScriptを埋め込んだ画像を作ってみました

寺田さんの日記に触発されて、JavaScriptを埋め込んだPNG画像を作ってみました。
注意:この画像にはJavaScriptが埋め込んであります。
私の娘が書いた絵ですここをクリックすると、JavaScriptが発動し、あなたのクライアント上でCookieの値を表示します(IE限定です)

追記 ImageMagic の convertコマンドでPNG→GIF→PNGと変換しても、JavaScriptは削除されませんでした。これは、T.Teradaさんの解説の追試に過ぎませんが、一応ご報告まで。

追記(2007/10/10)

MS07-057のパッチを適用したところ、PNG画像は正しく画像として認識されるようになり、JavaScriptも起動しなくなることを確認しました。手元のIE7にて確認しております。

本日のツッコミ(全3件) [ツッコミを入れる]

_ はせがわ [GIF/JPEGでもこのようなXSSする画像はありますでしょうか?]

_ 徳丸浩 [はせがわさんのブックマークを見て、公開をすることにしました:-)なんだ、もう公開されているんだ、って。 GIFは試し..]

_ はせがわ [ありがとうございます。そうですね、2年前とは状況が変わってますね。また時間のあるときにいろいろ書いてみます。]


2007年07月16日 再開

_ 再開しました

しばらくSPAM対策のため日記を閉鎖しておりました。 本日再開しますのでよろしくお願いいたします (_ _) 少しだけSPAM対策したけど、どーかなぁ


2007年06月14日 変数に型のない言語におけるSQLインジェクション対策に対する考察(4)

_SQLの「暗黙の型変換」で実行速度が遅くなるのはどのような場合か

数値リテラルをシングルクォートで囲むことの是非にて、「変数に型のない言語」(Perl、PHP、Rubyなど)で数値項目に対するSQLインジェクション対策について検討した。その際に、数値リテラルを文字列リテラルとしてシングルクォートで囲む(中の値はエスケープする)という方法を紹介した上で、文字列型から数値型への「暗黙の型変換」により、SQLの実行が遅くなる可能性を指摘した。
 この情報は、ネット上で検索すればすぐに見つかるものであるが、私自身試したことはなかった(なにせ暗黙の型変換などやりたくないクチなので)。
 しかし、実験もせずに「SQLの暗黙の型変換はパフォーマンスが劣化する」と断言するのもエンジニアとしてどうかと思い、簡単なサンプルで実験を行ってみた。
 実験には、Oracle Database 10g Express Editionを使用して、TKPROFユーティリティにより測定を行った。ただし、データ量が1万件しかないので実行速度については有意な差が出なかったので、インデックスの利用有無により間接的な判定を行った。
 結論から言えば、SQLインジェクション対策時に発生する「暗黙の型変換」については、パフォーマンスは低下しないようである。
 「暗黙の型変換」でパフォーマンスが低下する場合は確かに検証できたが、

文字列型の列と数値リテラルに対する演算

の場合であった。具体的には、以下のような場合である(DOC_IDは文字列型とする)。

SELECT * FROM HOGE WHERE DOC_ID = 123

この場合、すべてのDOC_IDを数値に変換しながらWHERE句が実行されるため、インデックスを使用することができずにパフォーマンスが低下する。
一方、DOC_NIDが整数型だとして、

SELECT * FROM HOGE WHERE DOC_NID = '123'

の場合は、まず'123'を整数型に変換してから検索実行されるので、インデックスが有効活用される。すなわち、パフォーマンス低下はない。
SQLインジェクション対策にあらわれる「暗黙の型変換」は後者のパターンであるため、SQLインジェクション対策に限って言えば、パフォーマンス低下は認められなかった。

しかしながら、このような実験を行うとともに、この問題に対する考察を深めた結果、やはり数値リテラルをシングルクォートで囲むというやり方には問題があると思う。その内容については稿をあらためて説明したい。


2007年06月05日 はてなダイアリーから転載

_Firefox 2.0.0.4におけるXSSワンクリックパスワード窃取問題

Firefox2.0.0.4でも直ってないですね。

ockeghem(徳丸浩)の日記 - Firefoxのパスワード・マネージャの脆弱性その後

Firefoxユーザーがクロスサイト・スクリプティングXSS脆弱性のあるWebサイトパスワードを記憶させている場合には,細工が施されたリンクをクリックするだけでそのパスワードを盗まれる恐れがある

直す方法はあると思うんだがなぁ。勝手に全自動でパスワード補完しないで、Operaみたいに一回キーを叩かせるだけでも、インパクトはかなり緩和されると思います。

まぁ、サイト側にXSS脆弱性がなければ上記は発動しないので、「けっ、サイト側の問題ジャン。XSSくらい直せよ」と思っているんだろうね>Mozilla中の人

だけど、XSSのあるサイトなんて山のようにあるよ。それも、はせがわさん(id:hasegawayosuke)の指摘するようなマニアックなやつでなくて、ごく単純なXSS

とりあえずは、

ということで自衛しましょう。


2007年06月04日 本格運用開始

_tDiary: html_anchorを導入

yyyymmdd.htmlでアクセスできるようにしたかったので、html_anchorを導入したはよかったけど、.htaccessでActionディレクトティブではまってしまった。これ、mod_actionsが導入されていないと駄目なのね。考えてみれば当たり前なのだけれど、「mod_actionsが導入されていることを確認せよ」と指示されてなかったので、試行錯誤してしまった。結局、Actionディレクティブをあきらめて(共用レンタルサーバーなので)、ErrorDocumentディレクティブに変更して、こちらはあっさりと動きました。
うーむ。

まぁ、ErrorDocumentとActionの二つが書いてあって、ErrorDocumentのデメリットは書いてあったけど、Actionのデメリットは書いてなかった。二つの方法があるなら、メリットとデメリットがあるはずとぼんやり感じていてた「変だなぁ」のだけど、そこらを突っ込まなかったのが悪いのですね。

とはいえ、これで、はてなダイアリーからの移行が可能になった・・・と思っています。だって、「?date=yyyymmdd」だと、全然検索エンジンに登録されないようですしね。


2007年05月31日 恐ろしい毒

_IEEE754のとりうる整数の範囲

hnwさんの日記は一見すると平易だが、恐ろしい毒がこっそり忍ばせてある。読者は表向きの平易に書かれたウンチクを楽しみながら、裏の毒を味わうという二重の楽しみを体験することができる。

今日はPHPのround関数に関して前回と違った切り口で紹介してみます。また、コンピュータ上での整数についても少し紹介してみます。

前回の記事「PHPの奇妙なround関数」(id:hnw:20070515)を読んで、小数点が付いた数なんてPHPで触ったことないから関係ないや、なんて考えた方が居るかもしれません。そんな方のために、今回は整数を四捨五入してみます。

[hnwの日記 - round関数で整数を四捨五入してみるより引用]

今回の毒は、以下の部分だ。

そして、IEEE64bit浮動小数点数であれば仮数部が52bitありますので、-2の53乗から2の53乗(約9000兆)までの整数は全て正確に表現できます。つまり、今回登場した変数値はどれも見た目通りの整数です*1。

仮数部が52bitあると、どうして2の53乗までの整数が表現できるのか、それを理解するためには、2進浮動小数点数の内部表現についての理解が必要となる。

一般に、2進浮動小数点数は、以下のような内部表現をとる。

± 1.bbbbbbbbbbbb × 2^nnn

1.bbbの部分が仮数部である。仮数部の最上位桁が1固定になっている理由は正規化をしているためである。そして、最上位桁が1と決まってるからには、わざわざメモリ上の1ビットを割り当てる必要がないことから、現実のメモリ上の表現としては省略している。これをケチ表現(economized form)と呼ぶ。すなわち、IEEE754形式の浮動小数点数は、実際には仮数部は53bitあるわけだ。
ここで、仮数部が全て1となる数を検討してみよう。

1.111 ..... × 2^52 = 2^53 - 1

であるので、2^53 - 1までは表現できることがまず分かる。
この数に1を足すと、有効桁数としては54ビットとなるわけだが、末尾が0であるので、

1.0 × 2^53

として正しく表現できる。この数に1を足すと、有効桁数が足らないので表現できない。すなわち、2^53が正確に表現できる整数の上限となる。

このようにして、1 ~ 2^53 までは表現できることがわかる。
負の数字については、符号ビットにより対応する。
ゼロについては、浮動小数点数の場合、特別扱いする必要があるのだが、IEEE754の場合は、前に述べた非正規化数の特別な場合(仮数部が全て0)として表現する。

符号なし2進52ビット固定小数点数の場合は、0 ~ 2^52 - 1 の範囲の整数を表現できるわけであるが、IEEE754は仮数部のケチ表現などにより見かけの有効数字を桁増しして、2^53までの数値を正確に表現できる。巧妙な手法である。

このように複雑な内容を、hnw氏はサラリと書き流し、読者がワナに掛かるのを待っているのである。
まことに恐ろしい毒と言わざるを得ない。

本日のツッコミ(全1件) [ツッコミを入れる]

_ hnw [お褒め頂いてありがとうございます。僕自身「doubleで表現できない最小の自然数は2^53+1である」ということに最..]



[PR]小規模ECサイトに最適なWAF、SiteGuard Lite

ockeghem(徳丸浩)の日記はこちら
HASHコンサルティング株式会社

最近の記事

最近のツッコミ

  1. DOMO (06-09)
  2. 徳丸浩 (09-02)
  3. rna (09-02)
Google