[PR]小規模ECサイトに最適なWAF、SiteGuard Lite
徳丸浩の日記
2007年09月05日 そろそろ入力値検証に関して一言いっとくか
_ Webアプリケーション脆弱性対策としての入力値検証について
Webアプリケーションのセキュリティ対策としての「入力値検証」について色々言われている。セキュアコーディングの基本は入力値検証だといわれたり、さほど重要でないと言われたりしている。本当のところはどうなのだろうか。以下、バイナリデータを扱う場合の多いミドルウェア(Webサーバーなど)と対比しながら、この問題を掘り下げたい。
バイナリデータの場合(≒ミドルウェアの場合)
バイナリデータでは、入力検証が重要である。少し前にmod_imagefightを取り上げた(画像版サニタイズ言うな(2))ので、ビットマップ画像を例に説明しよう。その際に使用した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:カラーパレット ZZZZ:ビットマップヘッダの中には、サイズに関連する値が多いことに注意されたい。
例えば、実際に受け取ったファイルのサイズと、BMPヘッダ中の「ファイルサイズ欄」が矛盾したら処理が継続できない。また、イメージの横幅と高さを鵜呑みにしてメモリを確保していたら、これらに巨大な値を入れるだけで(画像の中身は送らなくても)、アプリケーションは巨大なメモリをアロケートしようと試みるので、簡単にDoS攻撃が成立してしまう。また「ピクセルあたりビット数」が「1,4,8,24」のいずれかになっていることもチェックする必要があるだろう。
BMPの例に限らず、一般にバイナリデータの形式は、「データ長」に続いて「データ本体」が続く場合が多い。このデータ長に間違ったあるいは巨大なデータが入っていることをチェックしなければ脆弱性の原因となる。「入力データのチェック」が必要となる所以である。
すなわち、バイナリ形式のデータを扱う上では、
・データの整合性を保証することにより動作を確実にする
・リソース割り当てを適当に制限してDoS耐性を持たせる
などのために、入力の検証は必須なのである。
また、ここで注目して欲しいことは、BMPの画像イメージの内容まではチェックしないことだ(圧縮されている場合は別)。
すなわち、入力のチェックといっても、データの中身をチェックするのではなく、いわばデータの構造や枠組みをチェックしていることになる。そりゃそうだろう。TCP/IPでやりとりできるデータに制限があったり(例えば「'」があればエラーになる)、勝手に書き換えられたり(たとえば「;」が「_」に置換される)、勝手に削除される(例えば「<」や「>」があれば削除される)としたら、TCP/IPは使い物にならなくなる。
Webアプリケーションの場合
Webアプリケーションの場合で考えると、入力データの構造のチェックとしては以下が考えられる。・HTTPヘッダ(Cookieなど)の形式チェック
・クエリ・ストリングの形式チェック
・POSTデータの形式チェック(application/x-www-form-urlencodedなどの)
これらは確かに必要だろう。しかし、これらチェックはアプリケーションの役目というよりは、ミドルウェアやライブラリの役目だ。ミドルウェア類からアプリケーションに渡されるデータは、データの中身であって、上記の形式チェックや構文解析は既に終わっている。
ミドルウェア側の構文解析などがすんでしまえば、入力データがいかなる値であっても、データを受け取った時点で直ちにセキュリティ上問題が起こるわけではない。問題が発生するのは、その値を使う時である(当たり前だ)。
その例として、クロスサイト・スクリプティング(XSS)やSQLインジェクションなどのインジェクション系脆弱性があり、値を使う時に(出力時に)エスケープなどを行う必要があるのだ。データを使う時にどの文字が問題になるかは、データの使い方(HTML、SQL、・・・)によって変わる。そのため、データを使う直前まで、エスケープなどの処理はできないことになる。
アプリケーションの入力チェックですべきこと
Webアプリケーションでも入力値のチェックはするべきであるが、それはセキュア・コーディングという意味においてではない。ユーザが間違ったデータを入力した場合にできるだけ早期に誤りを発見して、アプリケーションの信頼性を高めるという、ビジネス要件の意味合いからである。したがって、電話番号とか、価格とか、メールアドレスのように文字種や桁数などが限定される場合には、ぜひその形式になっているかをチェックすべきである。
しかし、住所欄や掲示板への投稿本文欄など、実質的に文字種を制限できない場合も多い。そのような場合には、入力チェックとしてできることは、せいぜい桁数(文字数)のチェックくらいである。
すなわち、そもそも入力チェック(文字種チェック)は出来る場合と出来ない場合があり、文字種チェックなどが脆弱性対策に(結果として)役立つ場合もあれば、役立たない場合もある。したがって、Webアプリケーションの場合、入力チェックは根本的な脆弱性対策にはなりえず、「やっておいた方がよい」という保険的な対応にすぎない。
まとめ
古典的なセキュアコーディングの原則の一つに入力値検証があることから、Webアプリケーションにおいても入力値検証が脆弱性対策の基本であるかのような説明を見かけることが多い。しかしバイナリデータを扱うミドルウェア等の場合、入力データの検証とはデータの枠組みの検査であって、入力データそのものの検査ではない場合が多い。一方、Webアプリケーションにおいて、入力値の検査は入力データそのものの検査を論じる場合が多い。ここにギャップがある。(Web)アプリケーションの場合、通常データの枠組みは解析済みであり、データそのものを受け取る。したがって、ミドルウェアなどの場合に比べて入力値検証の重要性は低い。一方、アプリケーションの場合、ビジネス要件に従った入力値検証は重要である。下表にこれらをまとめた。
ミドルウェア | アプリケーション | |
データの枠組みの検査 | 重要 | 重要でない |
データそのものの検査 | 不要な場合が多い | 重要(*1) |
このように整理すると分かりやすい(上記は大まかな議論であって、もちろん例外はありえる)。
従来混乱しがちだった「Webアプリケーションのセキュリティ対策における入力値検証」の意味を考える出発点として、新しい視点を提案するものである。
本日の日記はツッコミ数の制限を越えています。
_
"週"記:[webappsec] 徳丸浩の日記 - そろそろ入力値検証に関して一言いっとくか - Webアプリケーション脆弱性対策としての入力値検証について
(2007年09月07日 09:14)
とてもよくまとまってると思います。では、現状はどうなのか、というのを過去~最近の経験から。 「住所欄や掲示板への投稿本文欄など、実質的に文字種を制限できない」値に対してはエスケープするなど正しく実装されてることが多いです。それが要件として明記されている..
徳丸浩の日記 - そろそろ入力値検証に関して一言いっとくか - Webアプリケーション脆弱性対策としての入力値検証についてを表示したところ、以下のようになりました。 入力値検証の話題から、細菌対策の広告を出すとは・・・
XSS対策:JavaScriptのエスケープ(その3) - ockeghem(徳丸浩)の日記にて、JavaScriptのリテラルを動的生成する場合のエスケープ方法について検討したが、id:hoshikuzuさんから、考慮がもれているという指摘を受けた(2007-10-11 - hoshikuzu | star_dust の書斎 - JavaScript
本日のリンク元
その他のリンク元
- https://www.google.co.jp/ ×482
- http://www.tokumaru.org/ ×86
- http://d.hatena.ne.jp/ockeghem/20071021/1192986523... ×54
- http://lechenie-spajsovoj-zavisimosti.ru/ ×27
- http://google-kupon.ru/ ×27
- http://shinavmashiny.ru/ ×26
- http://www.feeriaclub.ru/ ×24
- http://fedek.ru/ ×24
- http://xn----7sbittjtdqw.xn--p1ai/ ×18
- http://www.wwalls.ru/ ×18
- http://www.gigaset.com.ua/ ×18
- http://watch-movies.ru/ ×18
- http://sovetogorod.ru/ ×18
- http://misstube.ru/ ×18
- http://getsport.co.il/ ×18
- http://xn----7sbcdncdwdrsn6b5a.xn--p1ai/ ×15
- http://www.magicblack.biz/ ×15
- http://videochaty.ru/ ×15
- http://tebato.ru/ ×15
- http://minecraft-time.ru/ ×15
- http://megakino.net/ ×15
- http://allpdfmags.net/ ×15
- http://www.tmzilla.com/ ×12
- http://www.spy-sts.com/ ×12
- http://vk.com/uralgidrorezka ×12
- http://sugvant.ru/ ×12
- http://smotretifilmi.ru/ ×12
- http://remont-mobile-phones.ru/ ×12
- http://profnasteel.com.ua/ ×12
- http://lego-kubik.ru/ ×12
- http://kinousers.ru/ ×12
- http://k-profil.com.ua/ ×12
- http://joomlamaster.org.ua/ ×12
- http://check-car.ru/ ×12
- http://0n-line.tv/ ×12
- https://www.google.com/ ×10
- https://www.bing.com/ ×10
- http://www.xme.ru/ ×9
- http://www.sakhboard.ru/ ×9
- http://www.parlux.ru/ ×9
- http://www.cocos2d-iphone.org/forums/topic/cookies... ×9
- http://www.bbkauto.ru/ ×9
- http://wpizde.ru/ ×9
- http://wmcash-change.com/ ×9
- http://tiande-club.com/ ×9
- http://sx1x.ru/ ×9
- http://svclim.ru/ ×9
- http://sugarkun.com/ ×9
- http://shop-electron.ru/ ×9
- http://runetkicom.ru/ ×9
- http://remont-komputerov-notebook.ru/ ×9
- http://positivetravel.ru/ ×9
- http://nissan.afora.ru/ ×9
- http://nakino.tv/ ×9
- http://mosvolos.ru/ ×9
- http://lenterda.net/ ×9
- http://lechenie-ot-spaica.ru/ ×9
- http://kurenie-spajsa.ru/ ×9
- http://ke6a.ru/ ×9
- http://kam-russia.ru/ ×9
- http://hdseven.ru/ ×9
- http://graphid.com/ ×9
- http://getseo.co.il/ ×9
- http://forminecrafters.ru/ ×9
- http://donbass-stroy.com/ ×9
- http://cavitime.com/ ×9
- http://autonowa.ru/ ×9
- http://afora.ru/ ×9
- http://zena-na-chas-moscow.ru/ ×6
- http://xn--80aeahghtf8ac5i.xn--p1ai/ ×6
- http://www.veditour.ru/ ×6
- http://www.vashposrednik.ru/ ×6
- http://www.tokumaru.org/was/ ×6
- http://www.ooo-gotovie.ru/ ×6
- http://www.oknosite.ru/ ×6
- http://www.norma-tm.ru/ ×6
- http://www.metak.msk.ru/ ×6
- http://www.koptims.tiu.ru/ ×6
- http://www.hypernote.ru/ ×6
- http://www.devnull.jp/tdiary/20070907.html ×6
- http://www.cashtitan.com/investors/index.php ×6
- http://wcb.su/ ×6
- http://vimax-original.ru/ ×6
- http://ublaze.ru/ ×6
- http://talking-tom-friend.ru/ ×6
- http://stal-ua.com/ ×6
- http://sportsystem.pro/ ×6
- http://sellonweb.ru/ ×6
- http://ruvideochats.ru/ ×6
- http://russiahair.ru/ ×6
- http://romhacking.net.ru/ ×6
- http://reallybigday.ru/ ×6
- http://pro-okis.ru/ ×6
- http://prank.su/ ×6
- http://nastroyka.biz/ ×6
- http://narkologiya-voronezh.ru/ ×6
- http://narkologiya-volgograd.ru/ ×6
- http://narkologiya-belgorod.ru/ ×6
- http://nalberan.com/ ×6
- http://mug-na-chas-moscow.ru/ ×6
検索
- 入力チェック アプリケーション ×4 / webアプリケーション 入力チェック EL ×3 / Webアプリ 入力チェック ×3 / Web チェック 文字種 ×2 / URL 検証 Web 脆弱性 ×2 / webアプリ 入力チェック ×2 / web 入力チェック ×2 / WEBアプリケーション 文字数制限 ×1 / web アプリ 禁則文字 ×1 / web アプリ 入力チェック ×1 / webアプリ IDチェック ×1 / webアプリ セキュリティ 検証 ×1 / webシステム 入力チェック 文字種 ×1 / webシステム 入力チェック ×1 / webアプリ javascript 入力制限 ×1 / web 入力値チェック シングルくぉーと ×1 / javascript 入力 文字種検証 ×1 / java バイナリデータ 入力チェック ×1 / ipa.br loc:JP ×1 / hiddenの値 入力検証 ×1 / XSS 入力値チェック ×1 / Webアプリケーション 入力チェック ×1 / web セキュリティ対策 入力値制限 ×1 / WEBアプリケーションにて入力値チェック ×1 / web 脆弱性 禁則文字 ×1 / SQLInjection 文字数制限回避 ×1 / SQL 文字種別のチェック ×1 / 検証データ 30文字 ×1 / 入力 検証できません ×1 / 入力 改竄 ×1 / 入力バリデーション セキュリティ ×1 / セキュリティ Web画面 入力桁数制限 ×1 / 脆弱性 エラー入力文字 ×1 / 脆弱性対策 入力禁止文字 ×1 / 検証 修正 入力 Webアプリ ×1 / 入力検証 否定 ×1 / 入力制限 WEB ×1 / 入力チェック web ap ×1 / バイナリデータ 入力チェック ×1 / バイナリ 入力チェック ×1 / セキュアコーディング 入力値検証 ログイン画面 ×1 / コーディング 入力値チェック シングルクウォート ×1 / アプリ 入力エリアチェック ×1 / SQL 入力値検査 ×1
[PR]小規模ECサイトに最適なWAF、SiteGuard Lite
HASHコンサルティング株式会社
最近の記事
- 2011年08月30日
- 1. RSSフィードをリダイレクトします
- 2011年07月01日
- 1.
- 2011年03月29日
- 1. PDO/MySQL(Windows版)の文字エンコーディング指定の不具合原因
- 2011年03月22日
- 1. PHP5.3.6からPDOの文字エンコーディング指定が可能となったがWindows版では不具合(脆弱性)あり
- 2011年01月27日
- 1. CSRF対策のトークンをワンタイムにしたら意図に反して脆弱になった実装例
- 2011年01月04日
- 1. escapeshellcmdの危険な実例
- 2011年01月01日
- 1. PHPのescapeshellcmdの危険性
- 2010年10月03日
- 1. 問題点の概要
- 2010年09月27日
- 1. 文字コードに起因する脆弱性を防ぐ「やや安全な」php.ini設定
- 2010年07月25日
- 1. ツッコミSPAM対策で、ツッコミ抜きのRSSフィードを用意しました
- 2010年07月01日
- 1. ぼくがPDOを採用しなかったわけ(Shift_JISによるSQLインジェクション)
- 2010年04月06日
- 1. PROXY(プロキシ)経由でのDNSリバインディングと対策
- 2010年04月05日
- 1. JavaアプレットのDNSリバインディングはJRE側で対策済みだった
- 2010年03月29日
- 1. DNSリバインディングによる無線LANパスフレーズの読み出しに成功
- 2010年03月25日
- 1. DNSリバインディングによるルータへの侵入実験
- 2010年02月22日
- 1. ケータイtwitter(twtr.jp)においてDNS Rebinding攻撃に対する脆弱性を発見・通報し、即座に修正された
- 2010年02月12日
- 1. かんたんログイン手法の脆弱性に対する責任は誰にあるのか
- 2010年01月18日
- 1. iモードブラウザ2.0のXMLHttpRequestでPOSTデータの扱いが困難になった
- 2009年10月19日
- 1. quoteメソッドの数値データ対応を検証する
- 2009年10月14日
- 1. htmlspecialchars/htmlentitiesはBMP外の文字を正しく扱えない
- 2009年10月09日
- 1. htmlspecialcharsのShift_JISチェック漏れによるXSS回避策
- 2009年09月30日
- 1. htmlspecialcharsは不正な文字エンコーディングをどこまでチェックするか
- 2009年09月24日
- 1. SQLの暗黙の型変換はワナがいっぱい
- 2009年09月18日
- 1. 文字エンコーディングバリデーションは自動化が望ましい
- 2009年09月14日
- 1. 既にあたり前になりつつある文字エンコーディングバリデーション
- 2009年08月05日
- 1. 携帯JavaScriptとXSSの組み合わせによる「かんたんログイン」なりすましの可能性
- 2009年03月28日
- 1. IPAは脆弱性の呼び方を統一して欲しい
- 2009年03月27日
- 2009年03月11日
- 1. U+00A5を用いたXSSの可能性
- 2008年12月22日
- 1. JavaとMySQLの組み合わせでUnicodeのU+00A5を用いたSQLインジェクションの可能性
例えば、バインドメカニズムがまだ広まっていなかった頃、数値型の SQLインジェクションを防ぐためには、入力値検証を行うのが一般的(*1)でしたから、“セキュリティの要請”として入力値検証が重要な面もあったかも知れませんね~。
*1) 型変換も一般的でしたけどw
s/上手/上図/ ですね :-)
私も基本はエスケープという考え方を広めていきたいと思っています。ただし、少し複雑なアプリケーションを作ろうとすると、「例外」という問題が発生する可能性が非常に高いのでは?と感じることが多くなってきました。最も単純と思われるSQLInjectionの対策にしても、バインドメカニズムが使用出来ないケースは存在します。
エスケープだけでは防げないセキュリティの問題は存在していて、それらは入力値検証によって対策しなければならないという現実もあります。その部分のフォローが必要かなと感じる今日この頃です。
また、セキュリティの要請ではなく業務要件という考え方は、いまいち理解出来ません。例えば、パラメータの改ざんにより本来アクセス出来てはならないデータにアクセス出来てしまう問題があったとしたら、それは一般的なセキュリティの問題ではないということでしょうか?
>エスケープだけでは防げないセキュリティの問題は存在していて、
>それらは入力値検証によって対策しなければならない
そんなケースはないと思いますよ。
>パラメータの改ざんにより本来アクセス出来てはならないデータにアクセス出来てしまう問題
業務要件としてのセキュリティ要件であって、セキュアコーディングの話ではないですね。
突っ込みありがとうございます>みなさま
ミドルウェアとアプリケーションの役割は、すぱっと分かれるわけでもないので、ここで書いた話が絶対不変の真理などというつもりはありません。こう考えたら、おおむねうまく整理できるのではないかという提案です。
あと、入力値検証というのはあくまで入力値を受け取った時点での検証であって、その値を使う時にチェックしなければならないケースはあり得ると思います。例えば、リダイレクタに指定するURLに改行が入っていないかとかです。しかしこれとて、リダイレクタのAPI側で本来チェックすべきものだと思います。
>そんなケースはない・・・
お、そうなんですか。私が知らない間に、言語は進化しているようですね。
>業務要件としてのセキュリティ要件・・・
なるほど、セキュリティ要件を書く人は大変ですね。
masaさん
意見を述べるなら根拠を出して表明するようにしませんか。
「俺は知ってるけどお前ら知らないから言えるんじゃ」
と言われているようにしか聞こえません。
masaさんの方が間違っているかもしれないのに、
手の内を明かさないのでは誰も否定できません。
続けて。
masaさん曰く
「パラメータの改ざんにより本来アクセス出来てはならないデータにアクセス出来てしまう問題があったとしたら、それは一般的なセキュリティの問題ではないということでしょうか?」
意味がわからないです。「パラメータの改ざん」と言ったらなんでもそれに該当しますし、「本来アクセスできてはならないデータにアクセスできてしまう」と言ったら、セキュリティ上の脅威のCIAのCの全部がそれなのですから、何のことを指しておっしゃているのか特定できません。
そんな質問をしておきながら、「それは一般的なセキュリティの問題ではないということでしょうか?」なんて「そんなわけねーだろ」と言わんばかりの質問を投げかけるのは失礼です。
> 別の通りすがりさん
すいません、例をあげます。
SQLInjectionでしたら、
"select * from usertable order by " + columName + asc_or_desc;
といったコードでSQLInjectionの問題が発生した場合です。クォートされない個所への文字列挿入全般の問題なので、他にも例はたくさんあるかと思います。
このような問題にエスケープで対策出来ますか?分岐ロジックを書いていますか?実際は、入力値検証で対応するのではないですか?
と、いうことです。
パラメータの改ざん・・・のくだりは、アクセス認可と置き換えればよいでしょうか。
http://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/102.html
ここの図5の三段階目の入力値検証をイメージしています。
カラム名なら「"」で括るのが正しいですよ。
カラム名に予約語があったら困るので当然そういう文法が言語に用意されているわけです。http://www.postgresql.jp/document/pg653doc/j/user/syntax.htm
「asc_or_desc」のところは、そういうSQL文の作り方をしちゃいけないってだけです。入力のところでvalidationしなければならないってものではありません。
図5のものは、今ここで言われている validation のことではありませんね。脆弱性対策というより元々仕様で要求されているセキュリティ機能の一つでしょう。それが見えてはいけないことが仕様で定義されていなければこれが欠陥なのかどうか機械的判別はできないわけで、検査者の視点で言えば、検査者はそのとき「見えてはいけないもの」だということを常識で判断するのでしょう。それは仕様に欠陥があるという話で、ここで言われている脆弱性対策としての validation とは関係がないでしょう。
別の通りすがりさん
> カラム名なら「"」で括るのが正しいですよ。
恥ずかしながら知りませんでした、ありがとうございます。この指定については少し調査してみます。
asc_or_descの問題は「そういうSQL文の作り方をしちゃいけない」と言われると、「検証済ならよいのでは?」と思ってしまいます。ただ、入力値検証で対応しなければならない訳ではないですね。すいません。
>・・・それは仕様に欠陥があるという話で、・・・
常識で判断出来ることを仕様に書かなければならないとしたら、「セキュリティ要件を書く人は大変ですね。」という感想に変わりはありません。
私は、hidden値やselectboxで選択された値など、ユーザに悪意がない限り通常は改ざんされることがないデータが改ざんされ、その結果システムに悪影響が及ぶならば、業務要件がどうであれセキュリティの欠陥だと考えていますので。
フレームを発生させてしまい申し訳ありません。
カラム名のクォートについて調査した結果だけ報告して最後とさせて頂きます。
PostgreSQL8.2.4で検証したところ、「"」によって「"」がエスケープされますので、SQLInjection対策として有効であることが確認できました。テーブル名やカラム名に含まれる特殊文字のエスケープに(データベース名にも)適用が可能な、エスケープ関数が用意されている言語も多いようです。
http://www.go-pear.org/manual/ja/package.database.mdb2.intro-quote.php
http://msdn2.microsoft.com/ja-jp/library/system.data.common.dbcommandbuilder.quoteidentifier(VS.80).aspx
asc_or_descの部分は、「動的な入力値をそのまま使用して構文を組み立ててはいけない」と、理解することが出来ました。
不快な思いをさせてしまった方には深くお詫び致します。