<前の日記(2006年10月29日) 次の日記(2006年11月15日)> 最新 編集

高木浩光@自宅の日記

目次 はじめに 連絡先:blog@takagi-hiromitsu.jp
訪問者数 本日: 1668   昨日: 2574

2006年11月04日

駄目な技術文書の見分け方 その1

はてなブックマークのホッテントリを見ていたところ、300を超えるユーザに登録された以下の記事があった。

また上野宣か。顔見知りなのでズバリいくことにする。

しかし、その対策はまだ本当に理解されていないように思える。

へえ。

終わりの方を見てみると、

Webアプリケーションの対策

  • 入力値のSQLの特殊文字を適切にエスケープ
    入力値=プログラム(プロセス)に外部から入ってくるもの
  • シフトJISの場合には1バイト文字を整理
  • SQLの記述をなくすためにO/R(Object/Relational)マッピングを活用
  • 攻撃者に役立つ情報を与えないために、不要なエラーメッセージ(データベースが出力するエラーなど)の表示を抑止

対策に「準備された文」(prepared statement) のことを書かないのは、どういうつもりなわけ?

「入力値をエスケープ」だあ? いまだにサニタイズ脳から抜けられないのかね君は。「サニタイズ」って書かなきゃいいってもんじゃない。言っていることはサニタイズそのものなんだよそれは。どうして入力値だけをエスケープするわけ? SQL文に埋め込むところで全部するよう解説しろって言ってるのに*1、まだわからんのかね。

戻ってみると、

この問題の対策としては、入力値には半角英数字のみを許可するよう制限する方法や、以下の例のようにSQLで使える特殊文字をエスケープして対処するという方法が一般的になっている。

そんな方法が「一般的になっている」なんて書くなって。そんなのは、はじめっから間違ってるって書くべきこと。

この対策自体の方向性は正しいのだが、SQLインジェクションを理解していないため、対策が漏れている場合がある。

「方向性は正しい」と言いながら「理解していないため」というのはどういう了見なわけ? 「方向性」って何? 方向性からして間違ってるんだって。

■セカンドオーダーSQLインジェクション

SQL インジェクション対策として、入力値を適切にエスケープするという対策を行うが、この「入力値」が何なのか間違えていたり、チェックが漏れている場合がしばしば見受けられる。また、HTMLを生成する段階でエスケープすればよいと考えている人も見受けられるが、それも間違いである。

「入力値が何なのか」なんてぜんぜん考えなくていいっての。「チェックが漏れている」? どこでチェックするの? 入力からSQL文までのデータフローパスのどこかでとでも言うのかい?

「HTMLを生成する段階でエスケープすればよいと考えている人」って何それ? HTML? むりやり勘違い例を捏造してどうすんの? 「SQL文を生成する段階でエスケープすればよい」が正しいのをわかってて、わざと違えているわけ?

フォームに入力可能な部分だけが対策個所ではない。不正な入力の可能性を考える必要があるのは、GETやPOSTなどのクエリーやCookieの値、 HTTPヘッダなど、HTTP経由で送られてくるもの“すべて”と、それに加えてデータベースやファイルなどに保存されたデータを呼び出す際にも対策を怠ってはならない。ここに問題があると、セカンドオーダーSQLインジェクションと呼ばれる脆弱性を持つことになる。

ほら出た。ハッカー様の出番ってわけだね。利権構造ですかこれは。本当の解決方法を教えると出番がなくなるってか?

セカンドオーダー云々なんてどうでもいいの。普通の開発者は覚えなくてよい用語。これは攻撃手法の用語であって、間違った方向性の対策がされているときにのみ意味のある話で、はじめから正しい対策を理解すればよいだけの話。

SELECT name FROM user where uid = '$uid' AND age > $age

このSQLに渡される$uidと$ageの特殊文字は、適切にエスケープされているとしよう。

おいおい、「$age」を「'」で括っていない段階で「$age」が「適切にエスケープされている」って何言ってんの? 「'」をエスケープするという概念が生ずるのは「'」で括っている中においてだってことが、まだわからないのかね。

この問題は、ageの値がシングルクオーテーションで囲われていなかったことが原因である。以下のように囲われていれば、この問題は起きることがない(もちろん、数値以外は受け付けないという前段階の処理も欲しい)。

SELECT name FROM user where uid = '$uid' AND age > '$age'

「囲われていなかったことが原因である」と簡単に言うが、なぜ囲われていなかったのかについては言わないの? 数値フィールドを文字列で比較するとSQLではどうなるの? 文字列が数値に自動変換されるのはSQLの仕様なの? それとも実装依存でたまたま動作するの?

「(もちろん、数値以外は受け付けないという前段階の処理も欲しい)」ってのは何なの? SQLインジェクション対策として言ってるのか、それとも別の話をしているの? 他の人がこの問題への対策にその手のことを書いてるから、なんとなく書かないとまずいと思った?

■マルチバイト文字の問題

(略)

PHPならばaddslashes()といった関数を使って、フォームから受け取った入力値に含まれる「'」を「\'」と置換するなどの処理をしてSQLインジェクションによる攻撃を回避しようとするかもしれない。(略)

ポイントとなるのは「\x97'」の部分で、これの「'」をエスケープするために「\'」と置換すると「\x97\'」となる。(略)

\x97\x5C\x27 → 予'

こんなのは PHPのバグでしょ。エンコーディングがShift_JISの文字列を addslashes() するときに、Shift_JISとして処理していない addslashes() のバグ。なぜそれを言わないで、Webアプリプログラマの責任であるかのように書くわけ?

そして結論部分はこう。

また、どれも1つだけで決定的な手段というわけではないので、対策の際には併用してセキュリティレベルを高めることをお勧めする。

出た。「ぼくちゃんよくわからないから、とりあえず併用せよって解説しとけばいいよね」ってか?

SQL文の作成を正しく行うという「1つだけ」の方法で「決定的手段」なのに、なんで併用とか言い出すわけ? たくさんのSQL文があるときに漏れが生じるからということが言いたいなら、そう書けばいい。

去年4月のときにも似たようないい加減なことを書いていたよね。

  • 「ぼくはまちちゃん」 ――知られざるCSRF攻撃, 上野宣, @IT, 2005年4月27日

    この方法は簡単に実装できて比較的効果の高い方法である。しかし、リファラー情報はリクエスト発信者が自由に発行できる情報であるので、偽装されてしまう恐れもあり100%防ぐといった効果はない。

「100%」て何? 攻撃を防ぐ話をしているのだから、防げないなら対策じゃないでしょ。(しかも、CSRFの文脈でRefererは偽装できないと言ったのに、まだ直してないね。去年会ったときに、「直します」って約束してたよね?)

マスコミの記事でよく見かける表現に、「完全に○○ないわけではない」というものがあるが、これは断定できないことを言うときの逃げ口上だってことを知っておいたほうがよい。マスコミには許されるが、技術文書には許されない。技術文書なら、前提を明らかにした上でその前提の上で何が言えるかを書くのであって、例外があるなら例外を書くようにする。

セキュリティの解説で「どれも完全じゃないからいろいろやっておこう」という表現が出てきたら、その著者は信頼するに値しないと判断してよい。書いてる当人がわかっていないから、問題を整理できていないから、そういう表現が出てくる。

本日のTrackBacks(全12件) [TrackBack URL: http://takagi-hiromitsu.jp/diary/tb.rb/20061104]

高木浩光@自宅の日記 駄目な技術文書の見分け方 その1 @ITなんかは技術者には結構読まれていると思いますが、意識の低い不勉強な技術者は「ここに書かれていることをやったから大丈夫です!」と言ってしまう事があるし、ユーザー側も不勉強であれば「ここに書かれているこ

高木浩光@自宅の日記 - 駄目な技術文書の見分け方 その1 こちらの方でかなり厳しく言われてしまったので、反省する点は反省して見直し作業も進めることにする。 とりいそぎ、高木先生が最後の方で言っている下記の点は本当に忘れていたので、早速修正することにしました。

高木浩光@自宅の日記 - 駄目な技術文書の見分け方 その1 また上野宣か。顔見知りなのでズバリいくことにする。 はい、お手数をおかけします。 次回から指摘していただけるようでしたら、私信で頂けると嬉しいです。 対策部分は高木先生の指摘を加味して修正することにしま

できます。これはApacheのExpectヘッダでのXSS(参考:secuina)で知られるようになってきた現象ですかね。あまりこの手の話はみかけないけど。 今ここらへんで話題になってます。 駄目な技術文書の見分け方 その1(高木浩光@自宅の日記) Flashを使えばRefererが偽装できる?(

むしろ高木さんの方がなんか勘違いがある気がします. ■マルチバイト文字の問題 (略) PHPならばaddslashes()といった関数を使って、フォームから受け取った入力値に含まれる「’」を「¥’」と置換するなどの処理をしてSQLインジェクションによる攻撃を回避しようとす..

また上野宣か。 高木浩光@自宅の日記 - 駄目な技術文書の見分け方 その1 NGワードなんだ。(´_ゝ`).。oO(ふーん……) マスコミの記事でよく見かける表現に、「完全に○○ないわけではない」というものがあるが、これは断定できないことを言うときの逃げ口上だってことを

高木氏のエントリ駄目な技術文書の見分け方 その1の反応を見ていたのだが、どうも高木氏の主張が理解できてないor間違って伝わっているような気がするので補完してみる(その補完が間違っている可能性もあるが)。

\x97\x5C\x27 → 予&#8217;
こんなのは PHPのバグでしょ...

「サニタイズ言うなキャンペーン」につち

■ 駄目な技術文書の見分け方 その473 ockehgemのブックマークを見ていたところ、13人のユーザに登録された以下の記事があった。 サイト脆弱性をチェックしよう!--第6回:SQLインジェクションの検査方法, 池田雅一, ZDNET Japan, 2007年11月26日 また池田雅一か。顔見知り

高木浩光@自宅の日記 - 駄目な技術文書の見分け方 その1

検索

<前の日記(2006年10月29日) 次の日記(2006年11月15日)> 最新 編集

最近のタイトル

2016年04月23日

2016年04月06日

2016年03月27日

2016年03月14日

2016年03月06日

2016年02月24日

2016年02月20日

2016年02月11日

2016年02月05日

2016年01月31日

2015年12月12日

2015年12月06日

2015年11月23日

2015年11月21日

2015年11月07日

2015年10月20日

2015年07月02日

2015年06月14日

2015年03月15日

2015年03月10日

2015年03月08日

2015年01月05日

2014年12月27日

2014年11月12日

2014年09月07日

2014年07月18日

2014年04月23日

2014年04月22日

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|05|06|07|08|09|10|11|12|
2012|02|03|04|05|06|07|08|09|
2013|01|02|03|04|05|06|07|
2014|01|04|07|09|11|12|
2015|01|03|06|07|10|11|12|
2016|01|02|03|04|
<前の日記(2006年10月29日) 次の日記(2006年11月15日)> 最新 編集