« ホワイトリストとブラックリスト - Firewallの場合乱数生成器の取扱い - PHPとPython »

11 comments

Comment from: 徳丸浩 [Visitor] · http://www.tokumaru.org/d/
先日はお話できてよかったです。
「おまけ」に関して、小生の意見は以下のブログに書いておりますのでご覧ください。お忙しいようであれば、一番最近の「まとめ」をごらんいただければよろしいかと。

数値項目に対するSQLインジェクション対策のまとめ
http://www.tokumaru.org/d/20070924.html#p01

SQLの「暗黙の型変換」で実行速度が遅くなるのはどのような場合か
http://www.tokumaru.org/d/20070614.html

数値項目に対するSQLインジェクション対策
http://d.hatena.ne.jp/ockeghem/20070503/1178208149

数値リテラルをシングルクォートで囲むことの是非
http://d.hatena.ne.jp/ockeghem/20070502/1178042280

変数に型のない言語におけるSQLインジェクション対策に対する考察(1)
http://d.hatena.ne.jp/ockeghem/20070501/1178039408
2008/09/29 @ 15:21
Comment from: 意味がわかりません [Visitor]
> 出力時にエスケープしない特権的な変数をホワイトリスト化し、最小限の特権的変数以外の変数全てを出力先の仕様にあったエスケープを行えば、コード監査が非常に行い易くなります。

それを「ホワイトリスト」と呼ぶから意味がわからない、と言われるのではないでしょうか。

ホワイト(ブラック)リストというのは、「素性のわからない何か」に対して、それがリストに含まれるかどうかで「ホワイト(ブラック)」か判断するもの、というのが一般的な意味でしょう。

変数というのはプログラマが自分で作った「素性のはっきりしたもの」で、その変数をどう扱うかを決めるのもプログラマなので、その扱いを決めるためのリストがあったとしてもそれは「ホワイト(ブラック)リスト」ではないと思います。
2008/10/01 @ 20:23
Comment from: おまけ [Visitor]
> Q: エスケープせずにバリデーションすれば良いのでは無いか?
> A: バリデーションでもOKです。しかし、できるだけ単純なセキュリティ対策がないか考慮し、その結果全てのパラメータを文字列として取り扱う事をお薦めしています。

「バリデーションでもOK」ではなくバリデーションを行った上でこの手法をとるならわかりますが、バリデーションの代わりにはなりません。クエリの失敗は想定していない状況でのみ起こるようにすべきで、単純な入力値の誤りでクエリの失敗が引き起こされるべきではありません。

セキュリティ以前の問題として、クエリの失敗がユーザーのtypoなのか致命的な別の問題なのか、いちいちデータベースが返すエラーメッセージを解析するんでしょうか。そんなことをするよりはバリデーションの段階ではじいた方が確実です。

そもそも、大前提として今や「変数を埋め込んだSQL」を用いること自体が間違いですが。変数は全てバインドパラメータで渡すべきです。より「単純な」方法なのになぜこちらを強調されないのでしょうか。

(当然この場合でも入力値の検証は必要です)
2008/10/01 @ 22:03
Comment from: Yasuo Ohgaki [Member] Email · http://www.ohgaki.net/
>「素性のはっきりしたもの」で、その変数をどう扱うかを決めるのもプログラマなので、その扱いを決めるためのリストがあったとしてもそれは「ホワイト(ブラック)リスト」

ホワイトリストとはリストの作り方(列挙の手法)のコンセプトです。出力の場合、特権(直接出力)を認める変数を列挙すればホワイトリストと考えれば自然だと思います。変数の扱いをホワイトリストの定義に従って決めれば良い、という単純な考え方です。

分り辛ければリストに従って出力をエスケープする関数がある事を想定すれば分り易いかも知れません。

とにかくアプリケーションにダメダメなコードが多い理由の一つは

>「素性のはっきりしたもの」で、その変数をどう扱うかを決めるのもプログラマ

といった考えに基づいて作っていたからです。数えきれないほどの失敗事例があります。

プログラマが勝手に決めるのでは無く、直接出力が必須かつ確実に安全な変数だけ直接出力するよう、プログラマの頭の中で変数が「白」なのか「黒」なのか良く考えてから直接出力する変数の列挙方法がホワイトリストの作り方と同じと考えています。

この考え方に従って、もっと分り易く、適切な用語(XSSよりJavaScriptインジェクション、HTMLインジェクションのように)があるのであればその用語を使っても良いのかもしれませんがより適切な用語は、今の所思い付きません。
2008/10/01 @ 22:15
Comment from: Yasuo Ohgaki [Member] Email · http://www.ohgaki.net/
> 単純な入力値の誤りでクエリの失敗が引き起こされるべきではありません。

懇親会のQ&Aなので当たり前の事は省略しています。フェールセーフやフールセーフ対策として安全に動的に生成されたSQLを実行する方法を議論していまた。

当たり前のセキュティ対策は既に行っている事が前提です。セキュリティの基本コンセプトである多重のセキュリティとして、クエリ実行前にチェックしてもOK、としています。

要するに入力バリデーションは当たり前で既に必要な対策済みである事が大前提、それでもチェック漏れや勘違い等でエスケープやバリデーションしないとSQLインジェクションが成功してしまうケースも考えられるので、多重のセキュリティとして出力前にチェックしてもOK、という事です。

懇親会の時も私が明確にフェールセーフ/フールセーフ対策と言っていなかったので理解されていない方もいらしたかもしれませんが、フェールセーフ/フールセーフを突き詰めて考えると、全部エスケープかプリペアードクエリが最良だと考えています。

これでもテーブル名やフィールド名の問題が残ります。ORMでも注意が必要になるケースもあります。これらは仕方ないので教育で対処するしか無いでしょう。
2008/10/01 @ 22:22
Comment from: 匿名希望 [Visitor]
> 懇親会のQ&Aなので当たり前の事は省略しています。フェールセーフやフールセーフ対策として~

ではなおさら"バリデーション*でも*OK"というのは意味がわかりません。バリデーションは当たり前のことではないのでしょうか。さらにそれにつなげて"しかし~"と書かれているので「バリデーションではじく代わりに使え」と読めてしまいます。さらに言うと、

http://gihyo.jp/dev/serial/01/php-security/0014

ではこれが"攻撃目的の入力の検出に使える"と書かれています。

当たり前の事をやった上でのプラスアルファであれば、検出できるのは攻撃目的の入力ではなく入力値の検証漏れではないでしょうか。前者であれば「検出できて良かったね」ですが後者では「プログラムに致命的なバグがある」ということになります。起きたことは同じでも意味は大違いです。
2008/10/02 @ 00:09
Comment from: 匿名希望 [Visitor]
ホワイトリストとはなんだ、という話をしているのに

> とにかくアプリケーションにダメダメなコードが多い理由の一つは
> >「素性のはっきりしたもの」で、その変数をどう扱うかを決めるのもプログラマ
> といった考えに基づいて作っていたからです。

という話をするから議論がかみ合わなくなるのでは。

> この考え方に従って、もっと分り易く、適切な用語があるのであればその用語を使っても良いのかもしれませんがより適切な用語は、今の所思い付きません。

だからといってホワイトリストと呼ぶのは適切ではない、という話です。

「全部エスケープしてから出力」という手法について主張されたいのであれば、ホワイトリストという誤解を招く言葉を使わない方がいいでしょう。

「変数を列挙したものもホワイトリストと呼んでもいいではないか」という主張をしたいのであれば、現在の方法への批判とかどうセキュリティに貢献するかという話はされずに、ホワイトリストとはなんぞやという定義に絞って話をされたほうがいいでしょう。
2008/10/02 @ 10:54
Comment from: Yasuo Ohgaki [Member] Email · http://www.ohgaki.net/
> ではなおさら"バリデーション*でも*OK"というのは意味がわかりません。バリデーションは当たり前のことではないのでしょうか。さらにそれにつなげて"しかし~"と書かれているので「バリデーションではじく代わりに使え」と読めてしまいます。

どこでどれくらいのエラー検出をするのか? という問題はシステム設計の問題です。

SQL文生成の場合、既にバリデーション済みの変数と想定されるもの(例えば、IDなど)に再度同じバリデーション処理(例えば、IDの場合、符号無し整数であること)を行うのはオーバーキルだ、と考えて良いシステムの方が多いです。出力の場合は「バリデーションではじく代わりに使え」(全部エスケープする)で十分でしょう。不十分と考えられるシステムであれば出力時もバリデーションすればよいでしょう。

フェイルセーフとフェイルディテクトは別の考え方になります。私が常に言っているのは入力時に厳しいバリデーションを完全に行いましょう、そして出力時には万が一バリデーションが不十分であったり、予想していない経路で改変された変数があっても、セキュリティホールにならない様に出来る限り安全に失敗するフェイルセーフを考えましょう、という事です。ほとんどのシステムでは出力時の不正な入力の検出はオプション項目だと思っています。

2008/10/02 @ 16:24
Comment from: Yasuo Ohgaki [Member] Email · http://www.ohgaki.net/
>> とにかくアプリケーションにダメダメなコードが多い理由の一つは
>> >「素性のはっきりしたもの」で、その変数をどう扱うかを決めるのもプログラマ
>> といった考えに基づいて作っていたからです。

>という話をするから議論がかみ合わなくなるのでは。

何故有用なのか理解されていないように感じたので事実を書いたまでです。

>> この考え方に従って、もっと分り易く、適切な用語があるのであればその用語を使っても良いのかもしれませんがより適切な用語は、今の所思い付きません。

>だからといってホワイトリストと呼ぶのは適切ではない、という話です。


明確にホワイトリストの定義を行い、出力時にも同じくその考え方が使え、ホワイトリストの考え方を適用した方が安全なコードになる、と言っています。

どうして「出力時にホワイトリストの考え方を適用するのが適切ではない」と考えられるのですか?

用語として利用方法がおかしいと思われるのであれば、ホワイトリストの定義を書かれて、何故適切でないか書かないと議論は進まないと思います。
2008/10/02 @ 16:30
Comment from: 匿名希望 [Visitor]
> どうして「出力時にホワイトリストの考え方を適用するのが適切ではない」と考えられるのですか?

そんな話はしていませんよ。用語の使い方についてしか述べていないのに、「手法」について反論されるので話がかみ合わないのです。
2008/10/03 @ 00:17
Comment from: Yasuo Ohgaki [Member] Email · http://www.ohgaki.net/
>> どうして「出力時にホワイトリストの考え方を適用するのが適切ではない」と考えられるのですか?
>そんな話はしていませんよ。用語の使い方についてしか述べていないのに、「手法」について反論されるので話がかみ合わないのです。

もともと「用語の正しい定義と利用」について異論があるなら「用語の正しい定義]を示し、正しい用法を例示しなければなりません。それをしないで「同じ手法」で「出力もより安全にできる」と解説してことがおかしいと言われても困ります。

これらを示さずに「間違っている」と言われても議論が噛み合ないのは当然ではないでしょうか?

間違っている、と指摘されているのですから、どこがどう間違っているのかご指摘頂けると助かります。この件に関する議論で明確な用語の定義や抽象的でない論理的なご意見はまだ頂いていません。

2008/10/07 @ 09:22

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
PoorExcellent
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)