SQLインジェクション対策はおすみですか? 開発開始時点からのコンサルティングから、公開済みWebサイトの脆弱性検査、 脆弱性発見後の適切な対策まで |
2007-09-09 入力値検証について(2)
● アプリケーションの先頭で行う入力値検証は業務要件により行うべし
前回のエントリ徳丸浩の日記 - そろそろ入力値検証に関して一言いっとくか - Webアプリケーション脆弱性対策としての入力値検証についての内容をもう少し突っ込んでみたい。
このエントリは、幸いにも何人かの人たちの建設的なコメントをいただくことができた。それにより、私自身の考えを整理し、深めることができたように思う。
T.Teradaの日記 - 2007-09-08
"週"記(2007-09-07)
今回は、入力値検証の中でも、特にアプリケーションの先頭で行う入力値検証として何をすべきかということに焦点を絞って議論を進めたいと思う。
その前に、まずHTTPの復習から。
HTTPリクエストは申請書にたとえると理解しやすい
この日記の読者の多くは先刻ご存知だと思うが、HTTPは非常にシンプルなプロトコルである。WebサーバはHTTPリクエストを受付け、HTTPレスポンスを返す。それを延々と繰り返す。HTTPリクエストには、ファイル名に加えて種々のパラメータをセットできる。このパラメータ類を「Webアプリケーションの入力」とここでは呼ぶことにしよう。具体的には、クエリ・ストリング、POSTパラメータ、Cookieなどである。
HTTPリクエストを発行する際には、通常はHTMLフォーム上で規定された形式に従うが、現実にはどのようなパラメータをどのようにセットすることも呼び出し側の勝手である。ここで、HTTPリクエストを申請書にたとえてみると、申請書の形式は一応HTMLフォームで規定されている。しかし、申請書記入者は、指定の申請書形式に従わずに、項目を勝手に追加したり、申請書指定の形式(文字種や文字数など)を無視して自由に項目を記述することができる。
アプリケーションが申請書を受け付けるかどうかは早期に決定したい
役所や銀行などで、申請書類を提出すると、まず窓口で、申請書が所定の書式に沿っているかをチェックされ、一箇所でも間違いがあると、つき返される。一方、書式に間違えがなければ、受理され、バックオフィスで処理されることになる。窓口での書式確認は、形式ばっているようにも見えるが、申請書の間違いにバックオフィス側で初めて気がついて、申請書が行ったり来たりする無駄を考えれば、一応の合理性がある。
これと似たことはアプリケーションにもある。HTTPリクエストに記載されたパラメータ類は、アプリケーションの期待する形式になっているかどうかは保証されていない。仮に、アプリケーションの処理が相当進んでから、たとえば必須項目が足りずに処理が継続できなければ、今までの処理をロールバックして「なかったこと」にしなければならない。場合によっていは、ロールバックができずに、オペレータの手作業により、リカバリーしなければならないケースもあるだろう。現実には、上記は相当低レベルな話であり、アプリケーションは以下のような入力値チェックを「処理に先立って」実施することになる。
・必須項目が揃っているか
・各項目は指定の書式(型、文字数など)に従っているか
・形式が決まっている場合のチェック(電話番号、メールアドレスなど)
これらのチェックが通れば、申請書は受理され、処理にまわることになる。さて、ここからが本題である。
申請書に相当するHTTPリクエストが受理される要件は、セキュリティ上の都合ではないはずである。例えば、以下のような会話はどうか。
役人:えーっと、中村さん、住所欄に「'」は使えませんよ。書き直してください。 中村:そう言われても、アパート名がこうなんだからどうしようもないでしょ。 役人:とにかく駄目なものは駄目です。別の文字にしてください(*1)。
(*1)うわ、サニタイズ言うな
すなわち、申請書が受理されるかどうかの条件は、原則として全て業務要件によって決まるはずである。通常、現実の申請書には、書式が詳しく説明してあり、その条件を満たしているにも関わらず返却されたら、申請者は相当ムカツクはずである。
ケーススタディ
さて、T.Teradaの日記には以下のコメントがあるが、
徳丸さんの日記は、ユーザがテキストボックスなどで自由に値を入力できる住所などのデータを主に対象としたものだと思う。
私は、ラジオボタン、チェックボックス、セレクトボックスなどの場合でも、業務要件として入力チェックをすべきだと思う。これは申請書のたとえで言えばこういうことである。
たとえば、申請書の「性別欄」には、「女」や「男」と文字で記述する場合もあるが、多いのは男の場合は「1」、女の場合は「2}と番号が記載してあって、番号に丸をつけるか、番号を記入欄に記載する。申請書にはその方法が指定されている。ヤカマシい役所であれば、「『男』と書かずに、1に丸をつけてください」と言われるかもしれない。
Webアプリケーションの場合で言えば、性別欄がラジオボタンになっていて、その値が男の場合は「M」、女の場合は「F」だとする。性別欄が「M」か「F」のいずれかでなければ処理を継続できないわけだから、この値チェックは業務要件として必要である。
一方、先のエントリで問題になった、任意列でソートできるテーブルの場合はどうか。
この場合、ユーザの入力は、ソート対象となる列指定である。列の指定方法はアプリケーションの実装として決めればよいわけで、列番号(1,2,3...)でも良いし、表の各項目の論理名であってもよいし、対応するDBの物理的な列名を採用することもできる(前回議論の対象になった方法はコレ)。私自身の好みでいえば、DBの列名を外部にさらすのは色々な意味で抵抗があるので、たとえば列番号を指定してもらって、アプリケーションの内部で列名に変換するようなロジックにするだろう。
いずれにせよ、「申請書」に書くべき内容はソート対象の列指定であるが、その書式はアプリケーションの要求として決まっているものであって、一種の業務要件としてチェックすべきだということである。列番号を指定するのであれば、整数であることや数値の範囲のチェックが必要であろうし、列の論理名あるいは物理名を指定するのであれば、名前のチェック(文字種ではなく、列名として存在するか)が必要である。これらはいずれもSQLインジェクション対策としては、そこまでやる必要はない。あくまで、アプリケーションを正常に動作させるために必要な条件である。
「システム起源のデータ」をどうするか
T.Teradaの日記には、Webアプリケーションには「システム起源のデータ」というものがあって、この場合は入力値検証をすべきであると指摘されている。現実のWebアプリケーションに「システム起源のデータ」が存在することを私も認めるものであるが、しかし、HTTPリクエストが必ずしもアプリケーションに制約されないという条件下では、「システム起源のデータ」をHTTPにより受け渡しすることは非常に危険だ。私は「システム起源のデータ」も(広い意味で)ユーザからの入力に限定すべきであると考える。先に述べたソート対象列の指定のその一例である。そして、ユーザからの入力であれば業務要件としてのチェックが可能であるが、そうでないもの(セッションIDなど)は、極力少なくするべきであると思う。この点についてはまた稿をあらためて説明したい。
まとめ
アプリケーションの先頭で行う「入力値検証」は、従来セキュアコーディングの文脈で語られることの多かったが、現実には業務要件として行うべきものである。そして、業務要件として受付可能なリクエストは、特別なことがない限り処理されるべきであり、逆に処理できないものは業務要件として、入力に制限が掛っているべきである。例えば、メールアドレスに改行が混ざってはいけないというのも、申請書(伝票)の書式として要求できるものであり、現実問題、改行の入ったメールアドレスには(セキュリティ以前に)処理できない。
さて、業務要件としての入力値検証を実施すれば、結果としてクロスサイト・スクリプティング(XSS)対策やSQLインジェクション対策にもなっているケースは多いが、これらインジェクション系脆弱性対策と、アプリケーションの先頭での入力値検証は別物として考えた方がよいと思う。アプリケーションにはバグはつきものであり、入力値検証が正しく実装されていない場合もある。また、アプリケーションの脆弱性検査や保守をする際に、入力値検査で「検査済み」の項目と、それ以外の項目(入力値でないものも含む)を明確に区別することが難しいことによる。入力値検証が業務要件チェックとして行われている以上、脆弱性対策はそれら値を使う時(出力時)にすべきものとした方が、考え方がシンプルになり、アプリケーションの開発ライフサイクルのトータルで考えれば結局は安上がりになると考える。
- tDiary.Net ×1
- http://www.tokumaru.org/ ×146
- http://d.hatena.ne.jp/teracc/20070908 ×58
- http://d.hatena.ne.jp/teracc/ ×11
- http://b.hatena.ne.jp/keyword/XSS ×9
- http://tokumaru.org/ ×8
- http://b.hatena.ne.jp/entry/http://blog.ohgaki.net... ×8
- http://b.hatena.ne.jp/entry/http://d.hatena.ne.jp/... ×7
- http://b.hatena.ne.jp/t/入力値チェック ×6
- http://erokey.ddo.jp/diary2/rec/b/20070901.html ×5
- http://www.hash-c.co.jp/ ×5
- http://bakera.jp/ebi/topic/2986 ×5
- http://b.hatena.ne.jp/HiromitsuTakagi/?of=20 ×5
- http://hsj.jp/ ×5
- http://labs.ceek.jp/hbnews/ ×5
- http://www.devnull.jp/tdiary/ ×4
- http://d.hatena.ne.jp/ockeghem/about ×4
- http://www.devnull.jp/tdiary/20070907.html ×4
- http://b.hatena.ne.jp/ockeghem/imagefight/ ×4
- http://www.tokumaru.org/was/ ×4
- http://b.hatena.ne.jp/entry/http://www.tokumaru.or... ×4
- http://b.hatena.ne.jp/keyword/サニタイズ ×4
- http://www.about-reference.com/php/pear_manual/pac... ×4
- http://b.hatena.ne.jp/ockeghem/ ×3
- http://www.hash-c.co.jp/index.html ×3
- http://b.hatena.ne.jp/t/sqlインジェクション ×2
- http://b.hatena.ne.jp/t/SQLインジェクション ×2
- http://d.hatena.ne.jp/ockeghem/20070528 ×2
- http://www.tokumaru.org/d/20070905.html ×2
- http://a.hatena.ne.jp/harupu/ ×2
- http://www.tokumaru.org ×2
- http://b.hatena.ne.jp/entrylist?sort=hot&of=250&th... ×2
- http://d.hatena.ne.jp/tessy/?of=5 ×2
- http://b.hatena.ne.jp/Kanatoko/?of=380 ×2
- http://b.hatena.ne.jp/t/validation?sort=hot ×2
- http://b.hatena.ne.jp/keyword/SQLインジェクション ×2
- http://fastladder.com/subscribe/http://www.tokumar... ×2
- http://labs.ceek.jp/hbnews/list.cgi ×2
- http://b.hatena.ne.jp/entrylist?sort=hot&of=400&th... ×2
- http://b.hatena.ne.jp/n2s/ ×2
- http://b.hatena.ne.jp/HiromitsuTakagi/20070901 ×2
- http://b.hatena.ne.jp/Kanatoko/favorite ×1
- http://dragon.jp/column/archives/cookie.html ×1
- http://www.devnull.jp/tdiary/index.rb ×1
- http://b.hatena.ne.jp/pero1/favorite ×1
- http://r.hatena.ne.jp/keyword/SQLインジェクション ×1
- http://b.hatena.ne.jp/entrylist?sort=hot&of=400&th... ×1
- http://bakera.jp/ebi/2007/9/2 ×1
- http://d.hatena.ne.jp/ikepyon/ ×1
- http://www.devnull.jp/tdiary/200709.html ×1
- http://hsj.jp/index.html ×1
- http://b.hatena.ne.jp/t?tag=SQLインジェクション&of=25&sort... ×1
- http://r.hatena.ne.jp/pero1/セキュリティ/ ×1
- http://bluedot.us/users/tsupo/dot/92504698000 ×1
- http://r.hatena.ne.jp/yoiIT/受信箱/http://r.hatena.ne... ×1
- http://b.hatena.ne.jp/otsune/netwatch/ ×1
- http://b.hatena.ne.jp/nori0620/favorite?of=20 ×1
- http://del.icio.us/otsune?page=16 ×1
- http://b.hatena.ne.jp/HiromitsuTakagi/セキュリティ/ ×1
- http://b.hatena.ne.jp/t/入力値検証 ×1
- http://search.hatena.ne.jp/websearch?word=visibili... ×1
- http://b.hatena.ne.jp/entrylist?sort=hot&of=200&th... ×1
- http://b.hatena.ne.jp/naoya/favorite?of=150 ×1
- http://b.hatena.ne.jp/t/tksk ×1
- http://d.hatena.ne.jp/ikepyon/20070905 ×1
- http://www.tokumaru.org/index.htm ×1
- http://d.hatena.ne.jp/tessy/20070827 ×1
- http://d.hatena.ne.jp/keyword/サニタイジング ×1
- http://d.hatena.ne.jp/ockeghem/ ×1
- http://d.hatena.ne.jp/ockeghem/20070528/1180387214... ×1
- http://www.tokumaru.org/d/20080822.html ×1
- http://b.hatena.ne.jp/entrylist?sort=hot&of=150&th... ×1
- http://b.hatena.ne.jp/no_ri/20070910 ×1
- http://b.hatena.ne.jp/ockeghem/入力値検証/ ×1
- http://b.hatena.ne.jp/t/security ×1
- http://labs.ceek.jp/hbnews/list.cgi?k=5&p=3&c=0 ×1
- http://b.hatena.ne.jp/TAKESAKO/security/?of=20 ×1
- http://search.live.com/spresults.aspx?q=データ型変換 SQL... ×1
- http://www.yahoogle.jp/redirect.php?url=http://www... ×1
- http://b.hatena.ne.jp/TAKESAKO/20070910 ×1
- http://b.hatena.ne.jp/t/validation ×1
- http://d.hatena.ne.jp/ockeghem/20070911/1189483063... ×1
- http://b.hatena.ne.jp/entrylist?sort=hot&of=700&th... ×1
- http://hsj.jp/junknews/ ×1
- http://d.hatena.ne.jp/ockeghem/20070502/1178042280... ×1
- http://d.hatena.ne.jp/tessy/20070902/1188727522 ×1
- http://b2.hatena.ne.jp/t/validation ×1
- http://b.hatena.ne.jp/Kanatoko/ ×1
- http://b.hatena.ne.jp/entrylist?sort=hot&of=150&th... ×1
- http://tinyurl.com/preview.php?num=ynt7f3 ×1
- http://tokumaru.org/d/ ×1
- http://b.hatena.ne.jp/keyword/XSS脆弱性 ×1
- http://b.hatena.ne.jp/entrylist?sort=hot&of=100&th... ×1
- http://b.hatena.ne.jp/rna/prog/ ×1
- http://search.live.com/results.aspx?q=ラジオボタン リクエスト... ×1
- http://r.hatena.ne.jp/NSR250R-SP/受信箱/ ×1
- http://b.hatena.ne.jp/keyword/ロールバック ×1
- http://b.hatena.ne.jp/ever_rookie/favorite ×1
- http://b.hatena.ne.jp/keyword/Cookie ×1
- http://d.hatena.ne.jp/tessy/20070902 ×1
- http://b.hatena.ne.jp/HiromitsuTakagi/20070812 ×1
- XSS 検証 ×3 / webアプリケーション 徳丸 ×3 / xss 検証 ×2 / SQLインジェクション 入力値チェック ×2 / キーワード不明 ×2 / 入力値チェック html ×2 / インジェクション ラジオボタン ×2 / クロス サイト スクリプティング 対策 ×2 / mod_imagefight ×2 / javascript png 画像 ×2 / 入力値チェック ×2 / 徳丸浩 ×2 / 金床 セキュリティ ×2 / XSS 画像 ×2 / xss 対策 ×2 / webアプリケーション 入力チェック パラメータ ×2 / サニタイズ言うな ×1 / WEBアプリ 速度検証 ×1 / 一般的なWEBアプリケーションのセキュリティ対策 ×1 / 性別欄 1・2 ×1 / png ヘッダ カラーパレット ×1 / SQL 入力 検証 ×1 / 脆弱性対策 ×1 / twitter 文字化け ×1 / ラジオ ボタン サニタイズ ×1 / Ruby 入力チェック ×1 / javascript イメージサイズ ×1 / Web 入力値チェック ×1 / xss 検証方法 ×1 / 文字種 入力 検証 ×1 / HTML エスケープ & ×1 / XSS 方法 ×1 / 項目の論理名 ×1 / 画像XSS ×1 / quote mdb2 エスケープ ×1 / postgresql8.2.4 \ エスケープ ×1 / 入力値検証 ×1 / xss javascript ×1 / クロスサイトスクリプティング ラジオボタン ×1 / アプリケーション 検証 DB ×1 / SQL カラム名に予約語 ×1 / html 入力値検証 数値の範囲 ×1 / web プログラム サニタイズ ラジオボタン ×1 / WEBアプリケーション 入力制限 ×1 / クロスサイトスクリプティング ラジオ チェック ×1 / xss 入力チェック ×1 / JavaScript ラジオボタン 入力チェック ×1 / javascript selectbox 値チェック ×1 / IE 脆弱性 ヘッダインジェクション ×1 / php 1から100まで for ×1 / 画像 xss ×1 / web 前回入力値 ×1 / Imagefight2 ×1 / 掲示板 php エスケープ 一般 入力 ×1 / http POST 入力検証 ×1 / Webアプリケーション 検証 ×1 / 入力値チェック XSS ×1 / webアプリケーションの実装 ×1 / javascript 埋め込む 画像 xss ×1 / アプリケーション 要件 ×1 / アプリケーション 検証項目 ×1 / 入力チェック エスケープ ×1 / SQLインジェクション 入力値 チェック ×1 / 業務 入力検証 ×1 / sql 暗黙の型変換 ×1 / "論理名" "物理名" DB ×1 / 徳丸浩の日記 ×1 / FORM入力の検証 ×1 / sql 先頭 0 入力 ×1 / xss 入力値 ×1 / double 有効桁数 perl ×1 / WEBアプリケーション 業務 ×1 / SQL インジェクション やり方 ×1 / WEB 前回入力値 ×1 / webアプリケーション 脆弱性 チェック ×1 / 業務要件 ×1 / Webアプリケーション 入力制限 ×1 / html input 入力値 制限 数値 ×1 / Webアプリケーションの入力文字 ×1 / DbCommandBuilder.QuoteIdentifier ×1 / 入力値 ×1 / 入力値の判定 遷移処理 php ×1 / SQL SELECTリスト式の ×1 / ieee 754 有効桁数 ×1 / 徳丸 浩 ×1 / アプリケーション 入力 ×1 / web バグ 入力値 ×1 / terada 日記 画像 XSS ×1 / php 入力 検証 ×1 / javascript XSS チェック ラジオボタン 方法 ×1 / ieee754 ×1 / ruby メール 検証 ×1 / web アプリケーション 入力 チェック ×1 / Webアプリケーション 業務処理 検証 ×1 / IEEE 754 有効桁数 ×1 / web xss sql ×1 / DB 制約 数値 項目 先頭 ×1 / php bmp カラーパレット ×1 / セレクトボックス 入力チェック Webアプリケーション ×1 / SQLインジェクション DB 列名 ×1
SQLインジェクション対策はおすみですか? 開発開始時点からのコンサルティングから、公開済みWebサイトの脆弱性検査、 脆弱性発見後の適切な対策まで |