はじめに
前回セキュリティテストのための調査で、クロスサイト・スクリプティングについて調べましたが、今回はSQLインジェクションについて調べる上で知識が足りないと感じたので、調査していきます。
SQLインジェクションとは
どういう脅威?
SQL文の組み立て方法に問題があるとき、攻撃によってデータベースの不正利用を招く可能性がある脅威のことをSQLインジェクションの脆弱性と呼びます。
そして、これを悪用した攻撃をSQLインジェクション攻撃と呼びます。
SQLインジェクション攻撃
データベースに不正なSQL文を注入することで、機密情報の取得や改ざん、削除などの被害をもたらします。
これらはユーザ入力に対して検証が不十分だったり、エスケープ処理を適切にできていなかったりすることが原因で発生します。
発生しうる脅威の具体例
-
データベースに蓄積された非公開情報の閲覧
- 個人情報の漏洩
-
データベースに蓄積された情報の改ざん、消去
- Webページの改ざん
- パスワード変更
- システム停止
-
認証回避による不正ログイン
- ログインした利用者に許可されているすべての操作を不正に行われる
-
ストアドプロシージャ1等を利用したOSコマンドの実行
- システムの乗っ取り、他の攻撃の踏み台としての悪用
注意が必要なサイト
- データベースを利用するウェブアプリケーションを設置しているウェブサイト
- 個人情報のような重要情報を扱っている場合は特に要注意
対策
IPAのサイトでは以下のような対策が紹介されています。
根本的対策
①SQL文の組み立ては全てプレースホルダで実装する
- SQL文の雛形の中に変数の場所を表す記号(プレースホルダ)を置いて、その後そこに実際の値を機械的な処理で割り当てる方法
- SQL文の組み立て方法には文字列連結処理という方法もあるが、機械的な処理で組み立てる分、SQLインジェクションの脆弱性を解消することができる
②SQL文の組み立てを文字列連結により行う場合は、エスケープ処理等を行うデータベースエンジンのAPIを用いて、SQL文のリテラルを正しく構成する
- 処理を文字列連結処理で行う場合は、対象の値に対してエスケープ処理を行う必要がある
- データベースエンジンによってはそのための専用のAPIを提供している場合もあるため、必要に応じて活用する
- この処理はSQL文を構成するすべてのリテラルに対して行うべき
③ウェブアプリケーションに渡されるパラメータにSQL文を直接指定しない
- hiddenパラメータ等にSQL文をそのまま指定する実装は、データベースの不正利用につながるので避ける
保険的対策
①エラーメッセージをそのままブラウザに表示しない
- アプリケーション上にエラーメッセージを出す際、データベースに関連するメッセージをそのまま出してしまうと、SQLインジェクション攻撃につながる情報が含まれている可能性がある
- 特に、データベースの種類、エラーの原因、エラーを起こしたSQLに関する情報など
- そのため、それらの情報は利用者のブラウザに表示しない工夫が必要(別でメッセージを用意するなど)
②データベースアカウントに適切な権限を与える
- データベースアカウントに必要以上の権限が付与されていると、攻撃された際の被害が大きくなる恐れがあるため、必要最小限の権限を与えるようにする
SQLのプレースホルダーとは
パラメータ部分を「?」などの記号で示しておき、後で実際の値を機械的に割り当てることができます。
プレースホルダに実際の値を割り当てることをバインドするといい、いつそれを行うかによって種類が変わってきます。
このバインドするために使っている記号をプレースホルダと呼びます。
以下はIPAの別冊:「安全なSQLの呼び出し方」で紹介されている分類です。
静的プレースホルダ
- プレースホルダのままのSQL文をデータベースエンジンにあらかじめ送信して、実行前にSQL文の構文解析などの準備をしておく方法
- SQL文の構文はバインド前に確定し、後からSQL構文が変化しないため、最も安全である
動的プレースホルダ
- プレースホルダを利用はするけど、データベースエンジンではなく、アプリケーション側でバインド処理を実行する方法
- この方法は開発者によるエスケープ漏れを防止できますが、ライブラリによってはSQLインジェクションに対して脆弱性がある
Laravelでの対策
Laravalではプレースホルダを「:」を使って表すこともできます。
これにより、プレースホルダを多用した際にも指定を間違いにくくすることができます。
また、selectメソッドの第2引数は自動でサニタイズされ、SQLインジェクションを防止することができます。
Laravelで行えるSQLインジェクション対策については、まだ詳しくないので、少しずつ調べて行ってみようと思いました。
参照
別冊:「安全なSQLの呼び出し方」
-
ストアドプロシージャ・・・データベースに対する連続した複数の処理を1つのプログラムにまとめ、データとともに保存できるようにしたもの ↩