- - PR -
webアプリケーションの脆弱性
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-12-15 13:56
ども、ほむらです。
僕もCGIを書いている身として煮詰めてみたいので。。 -------------- がるがる氏へ 以下必要部分の順序を整理ながら 中略させていただいてますm(__)m
この動作はただしいと思います。 WebサーバーはContent-Lengthで指定されたサイズの入力があるまで リモートホストからの通信を待ちますのでデータのサイズが足りなければ タイムアウトになります。 また、タイムアウトになるときに送るといっていて実際のデータがきていないのですから Bad Requestも正常のように思います。 仕様からくる現象ですのでCGIでは対処出来ないでしょう。 ちなみに、SCOがされていましたね(笑。 このDoS攻撃に対する専用のセキュリティソフトはあるみたいですが。。
僕の書き方が特殊なのでしょうか? Perlでは、sysread(STDIN, $httpRequest, $ENV{'CONTENT_LENGTH'}); として記述しています。 この場合を考えたとき、Content-Lengthの値の大小にかかわらず 標準入力以上にはなりませんし、またContent-Lengthを超えることもありません。 危険だとすれば両方を大きくした場合ですがこれもCGIでは 微妙ではないでしょうか? まぁ、読み込む前に調節すればいいのかな〜 #個人的に思うにサイタイジング(?)でURLエスケープを忘れている人は時々いますね。 #日本語に対応していればそんなことはおこらないはずですけど | ||||||||||||||||
|
投稿日時: 2003-12-15 14:22
ども、ほむらです。
長くなってしまったので分けされていただきました。 ------- おばけ氏へ
ですね。同感です。 その関係でしょうか最近では、hiddenは使わずに Session変数を使用する場面がおおいみたいですね。 まぁ、だからといって安全になったということでもないかもしれませんが。 改ざんについてはだいぶ安心できる環境になってますよね。 #そのうち、hidden=セキュリティホールみたいな考え方の人がでてきそう(笑 ですが、僕の場合クッキーはほとんど使用したことはない(リロード対策くらい?)のですが hiddenはわりと使用します。(CGIなのでSessionが使えないんですよ(笑 ) 僕がhiddenで使用する対象になるのはCGIの内部で静的に定義されているデータ等や 読み取られても問題のないものです。 #最近タイムスタンプの使い方がわかったのでファイルを使用して #セッション変数もどきを作ろうかと計画中 | ||||||||||||||||
|
投稿日時: 2003-12-15 14:36
ども。がるです。
んと、同じく煮詰めたいネタなのでちと腰をすえて(笑 まず ・タイムアウトでDoSになる件 ですが。個人的には非常に微妙な扱いをしています。 というか、まず第一に 「どういう挙動の結果そうなるのか」 を認識していないケースが多くて。厳しい発言をするなら、 基礎動作をきちんと認識していない時点で「論外」と。 つぎに。 タイムアウト待ちは「わかっててやっていて」なお、非常に 微妙です。 仕様を突き詰めた結果として「リスク込みでそれでよい」となれば それでよいのだと思うのですが。 実際にはその辺のリスクを考慮せずに「何でこうなるんだろう?」 となるケースが多く。 この場合に、非常に危険であると思ってます。 というか、この攻撃、比較的軽いリソースで行えてしまうので、 考慮からはずすにはちと…って部分があるので、いつも悩みます。 個人的には実はCONTENT_LENGTHは無考慮にすることが多いです。 まぁそれはそれで色々リスクがあるので、その辺はいつも考察が 欠かせない部分なのですが。 ちなみに > 仕様からくる現象ですのでCGIでは対処出来ないでしょう。 そうでもないです。かなり環境は限定されますが。 知っている限り、C(およびC++)だと、非同期のread、というものが あるので、少なくとも「タイムアウトの時間を任意に制御」したり 「タイムアウトであることを明確に把握」したりすることが出来ます。 ただ…知っている限りでは、Perlでは無理ですねぇ。システムコール を直接呼べば可能なのですが(笑 > ちなみに、SCOがされていましたね(笑。 です。 あの辺が「リスクを飲んでの結果」かどうかはかなり微妙ですが:-P > Perlでは、sysread(STDIN, $httpRequest, $ENV{'CONTENT_LENGTH'}); 実データがCONTENT_LENGTH以上、の場合で危ないのは、実はCでCGI を書いているときが一番顕著です。 スクリプト系やC++でstringを使っているときは、言語のバックボーンが 動的なメモリ確保をやっているので比較的楽かなぁ、と。 双方とも大きくした場合は…C++は回避が簡単に出来るのですが (stringからの例外の捕捉)、Perlがもう一つ。 まったく対応できないわけではないのですが、比較的に面倒な うえにきちんと処理をしているケースがほとんどないですね。 この辺を色々考えるに、個人的には「業務のCGIをPerlで組む」 のに、一定レベルの抵抗感がぬぐえないです。 環境が許せばC++、ないし「徹底的に突き詰めるのなら」Cで 記述しています。…もっとも、最近はほとんどC++で楽をしており ますが(stringと、それ以上にclass、STLが手放せない)。 こーゆー部分って実はCGIの話ではずいぶんおざなりにされやすい 部分なんですが。 この辺をきちんと突き詰めておくと結構深くて面白いと思ってます。 # 次点は「セッションID」なのですが。 # そのうち突き詰めた話をぶちまけてみようかな?(笑 [ メッセージ編集済み 編集者: がるがる 編集日時 2003-12-15 14:49 ] | ||||||||||||||||
|
投稿日時: 2003-12-15 15:59
[quote]
がるがるさんの書き込み (2003-12-15 12:54) より:
あぁなるほど。いわゆるバッファオーバーフローの話ですね。 手元では Perl の CGI で試していたので、忘れていました。
これらはどんなプログラミングでも必要なことなのに、 なんで Web アプリケーションの場合はおざなりにされちゃうんでしょうかね。 [ メッセージ編集済み 編集者: bun 編集日時 2003-12-15 16:00 ] | ||||||||||||||||
|
投稿日時: 2003-12-15 16:10
ども。がるです。
厳密にはバッファオーバフロー「だけ」ではないですね。 単純に、あまり巨大な変数は取れない場合があるので(原因は色々)。 バッファがあふれないにしても、変数として「取得できない」、 さらには「落ちる」というケースがたまにあるので。 ちなみに、この辺のテストをすると「Linuxってもろいなぁ」とか 思います :-P そういう点で丈夫なのは例えばSolaris。Linuxは、2.4から大分 丈夫になってきたように思いますが…まだ微妙不安。
実はWebアプリケーション(ってかCGI)以外でも結構軽視されてます。 最近の風潮、って感じでしょうか? 最近のプログラマ/SEの方は、総じて基礎がしっかりしていないことが 多くて、上っ面だけ見て「こんなもんかなぁ」で終わってしまう ケースが多いように思います。 実際にはある程度便利な機能というのは使わないと(生産性があがらない ので)重要なのですが。 技術者たるもの、そのバックボーンに一度は思いをはせ、実装方法を しり、っていう作業が必要だと思うんですけどね。 あと、多いのが「単一主義者」。あらゆるものを「単一のOS」「単一の 言語」「単一のDB」「単一の**」で片付けようとする。 複数のものを学んで、そこからベストチョイスを探すのって技術者の 仕事の一つだと、それは今でも思っているのですが。 そこまできちんと勉強する人は少ないですねぇ。 ちょいと厳しめの意見を書いてみました ^^; | ||||||||||||||||
|
投稿日時: 2003-12-15 17:40
ども、ほむらです。
--------- hose氏へ スレとかけ離れていきそうなのでちょっと本題に Webアプリケーションの脆弱性として代表的な物は ・リクエストデータの未チェック(未修正)によるプログラムの実行など ・hiddenデータの加工 ・お気に入りや戻るなど想定外の経路 ・クッキーデータの盗聴・改ざん? とこんなところでしょうか? 加工や想定外の入力に関しては注意がいっているようですが 修正するロジックの中でただしいデータが別の形 (URLエンコードや本来入力されない書式) できた場合にスルーしてしまうこともあるみたいですね #IEの事を気にされているようですが、世間で言われているとおり #IEのセキュリティホールは似たようなものばかりです。 #(それも拡大解釈に起因するところが大きいようですね) ----- がるがる氏へ >タイムアウトでDoSになる件 これはあとでてくる、想定以上のばかでかいメモリ確保と同等ですよね。 タイムアウトする間にリクエストがどんどんきて、新しいプロセスが立ち上がって 結果として、リソース不足になってサーバーダウン。。。 でも、こうやって考えるとタイムアウトはしなくてもいいんですよね。 原因はシステムリソースの減少ですから。
非同期処理ですか。 それならば確かにタイムアウトの検知はCGIできますね。 ただ、その場合だとCGIのタイムアウト時間は サーバーのものよりも短くする必要がでてきますので、どうせならば タイムアウトを監視するのでなく、 読み込みのサイズを監視したほうがいいのではないかなと思います
PerlもCも同じだと思うのですが・・・・ 僕のプログラムの方法を中心に考えればContent-Lengthを使用するのならば 変数に保存してその変数を起点に処理していきますよね? たとえば query = (unsigned char *)malloc( contentLength ); fgets(stdin, query, contentLength);とか(?)
どうでしょう?やっぱり業務であってもCGIは多く使用されているのでしょうか? 個人的には業務ならばサーブレットや.NETの世界だと思うのですけど。。。 #STLは便利ですよね。 | ||||||||||||||||
|
投稿日時: 2003-12-15 18:47
ども。がるです。
です。この辺のリソース周りは、いつまでたっても面倒な話題 ですね(苦笑 でも、案外簡単に限界に引っかかる瞬間があるのが怖いです。
これは、私の場合は「どっちも」ですね。 マイクロスリープ(select)とかで一瞬ウェイトをおいて、読み込みが 進んでいなければきる、くらいの思い切った処理が、時々必要に なってます。 ただ、非同期はなれないと面倒なので、教育には苦労します(苦笑
基本はこのパターンです。 で、やはりこれで「CONTENT_LENGTHを信用してしまう」ミスをやった 時に、ある人から「-1が入ってきたら?」 と一言で片付けられて、目からうろこが落ちたことがあります。 # mallocで-1って挙動保証ないんですよね ^^; 結局このあたりは「どこを切り捨てるか」っていうかなりシビアな 議論になるので、一概に正解がないあたりが難しいですね。 私も「データを基準にする」時と「CONTENT_LENGTHを基準にする」 時と、ケースbyケースで設計していますね。
私はCGIで作成することが多いですね。 単純に「細かいところまで手が届く」ので。特にC++の場合。 サーブレットはすきなのですがJSPが嫌いだったり(人にも寄るのですが、 デザインとロジックが分離していないところが苦手:同様にPHPもだめ)。 .NETは色々あってまだ手を出していないですね(いやまぁ単純にWindows プラットフォームでの仕事をめったにしないだけなのですが。現状で、 Linuxで.NETを積極的に選択する理由も特に思い当たらないので)。 よく「大掛かりなものにはCGIは…」と倦厭する人が多いのですが、私の 場合、CGIで大掛かりなものを簡単に作る技術に慣れてしまったので、 あまり苦労はしてないです(笑 まぁ、この辺は「色々ためして」みつつ「どのような論点から」なにが ベストなのかを見極めていけるのがベストなんだろうなぁ、って思います。 なんか話しが微妙にずれてきたので、この辺で(笑 |