ご指摘のように、SQL文の一部に埋め込む変数が数値のみあるいは英字のみであることが確実であれば、SQLインジェクション脆弱になることはまずありません。しかし、プレースホルダ(:idの部分)を使ってSQLインジェクション対策をしましょうというのは、世界的なコンセンサスになっています。例えば、以下の記事をお読み下さい。
OWASPのSQLインジェクション対策方針を読んで「おまえは俺か」と思った
OWASPというのは、ウェブアプリケーションセキュリティの世界的な団体ですが、エスケープや入力値検証(バリデーション)による対策は完全なものにするとが難しいとした上で、プレースホルダによる対策を推奨しています。
冒頭で、数値のみあるいは英字のみであればSQLインジェクション脆弱性になることはまずないと書きましたが、変数の内容がメールアドレスであればどうでしょうか? 一般的に使われているメールアドレスは、英数字とハイフン、アンダースコア、アットマーク、ドットくらいしか使わないので、SQLインジェクション脆弱になることはないと思いがちですが、メールアドレスの規約であるRFC5322に準拠したメールアドレスであれば、SQLインジェクション攻撃が可能です。
XSSとSQLインジェクションの両方が可能なRFC5322適合のメールアドレス
つまり、自明な範囲を少し越えると、攻撃が可能になってしまう場合があるということです。
また、SQLインジェクション脆弱性が非常に危険であることもあらためて強調しておきたい内容です。以下の記事のように、SQLインジェクション脆弱性を作り込んでしまった結果、民事訴訟で 2000万円以上の損害賠償が課せられた判決(確定)があります。
SQLインジェクション対策もれの責任を開発会社に問う判決
このため、ごくわずかでもSQLインジェクション脆弱性が入り込む要素は取り除きたいところです。
そして、たとえば所属企業の社長が、上記の判決の記事を読んで、「我が社の開発コードにSQLインジェクション脆弱性はないか、再確認せよ」という指示があったとします。そして、例示されたSQL文を再確認したとします。
SQL
1$sql="SELECT * FROM table WHERE id > ${id}";
ミクロで見ると、SQLインジェクション脆弱性があるように見えます。しかし、すぐ上を見ると、$id = 2; があるので、SQLインジェクションではないことがわかります。
しかし、この例はいくらなんでも単純すぎますよよね。実際には、もう少し上まで見ないとSQLインジェクションがないことは分からない場合が多いでしょう。$idをフォームのバリデーションで数字のみであることを確認していたとすると、バリデーションはソース上では全然別の箇所に書かれているかもしれません。そうなると、確認には時間が掛かりますし、確認漏れの心配も出てきます。
つまり、プログラムは書きっぱなしになることは稀で、アプリケーションのライフサイクルにわたって保守していくものですし、SQLインジェクションの可能性をわずかでも取り除くためには、下記の特性が重要なのです。
- SQLインジェクションがないことが一目瞭然わかること
プレースホルダを使ったソースコードでは、SQLインジェクションがないことが一目瞭然で分かります。このような書き方で統一することで、わずかでもSQLインジェクション脆弱性が混入する余地をなくし、保守の際にも、一々SQLインジェクション脆弱性の心配をしなくてもすむことになります。
前述のように、SQLインジェクション対策は、技術的には複数の方法があるにも関わらず、プレースホルダによる方法に統一することが世界的な潮流になっています。それは、上記のような背景があるからだと考えます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/01/28 05:18