Twitter にて ikepyon が呟いていたのに反応してしまった。
なぜSQLインジェクションが亡くならないのか?ってのも、「セキュリティ基礎知識の理解不足」っていうより、SQL文と言語の習得が別々だからだと思うんだよなぁ。つまり、SQL文の理解や、言語の理解が不足している
これに対する私の発言は下記。
@ikepyon 違うと思うんだけど。ひとつの文字列としていろんなものを渡す方法そのものに問題があると思う。Injection されるのは SQL に限った話ではないし。
読み返してみると言葉足らずだなぁ。その点を見事に補足してくれました。
@tyappi そうですね。命令とデータを同じ文字列にごっちゃに記述できるのがSQLのいいところですが、これはデータ、これは命令みたいに意識しないといけないのに、それが理解できてないんじゃないかと・・・多分個々の問題としては理解できるんだけど、それらの連携が出来てないみたいな
世の中に ~ injection というものは XSS とか OS command injection とかいろいろありますけど、根本的な原因はこれなんですよね。命令と data を一つの文字列として渡してしまう。この方式がそもそも脆弱性を作る原因です。
なので、覚えておくのは一点でいいと思うんですよね。
命令と data を一つの文字列として渡せるものがあったら、その方式は使うな!
最初の内は構文をすべて理解するなんて絶対に出来っこないわけですから、しくみをちゃんとちゃんと理解する必要があるとか教えるというのにも無理があると思います。なので、できるだけ simple にする必要がありますね。
SQL を勉強するなら、"SELECT ~" とか "DELETE ~" とか習うと思ういます。その時、これは命令だよなというのは誰でも気付くと思います。
なので、できるだけ早いうちに「命令と data を一つの文字列として渡せるものがあったら、その方式は使うな!」という鉄則を叩きこんでおくべきだでしょう。
例えば XSS。HTML を学習している時
<SCRIPT> tag で program 実行できるじゃん -> 当然命令だよね -> 動的に生成するには気をつけないと。
例えば OS command injection。Shell ってそもそも命令渡しているよね。 -> "|" とか使うと複数の命令渡せるよね。 -> 動的に command 作って発行するのまずくない?
こんな風に考えてもらえれば第一関門は clear できます。こうゆうのが重要だと思うんですけどね。
あともう一つ重要なのは、初めから使って問題の無いもののみを教えること。ちゃんと基礎から理解してくれる人ならそんなことしなくてもいいんですが、すべてがそうではないので基礎を理解するためとはいえ、最初に問題のある方法を教えるのはまずいと思っています。
しくみを説明しないのであれば、問題の無い方法のみ教える。しくみを説明する場合でも、必ず問題のある方法と問題の無い方法を一緒に教えるようにする。これは絶対にはずしてはいけない要素だと思います。
で、話は戻りますが ikepyon の発言は下記資料を読んだ感想とのことです。
PostgreSQLユーザのためのSQLインジェクション対策
ざっと目を通しましたが、ある程度わかる人向けの資料ですね。この手の環境は得意ではないので深掘りは避けますが、いくつか気になったところが。
- 多重のセキュリティ対策が重要と言っていて database permission に全く触れていない
- Encoding の問題を指摘するのはいいんですが、だったらできるだけ encoding で問題が発生しない環境構築する方法とか、言語について言及すべき
このあたりが気になりますね。そもぞも、SQL injection なんてものは framework や library の利用によって完全に撲滅されるべきだと思っていますので、それにこたえられないものは利用しないというのが一番の解決策だと思うんですが。よく調査しないと落とし穴にはまりやすいというのも同様で利用しないに越したことない。