セキュリティは古くて新しい問題です。SQLインジェクションも古くからある問題ですが現在の問題です。対策は比較的簡単なのですが今でもなくなりません。と言うよりも今でも現役のセキュリティ上の問題で十分注意が必要です。この連載でも何度かSQLインジェクション対策について簡単に取り上げています。
- 第5回 まだまだ残っているSQLインジェクション
- 第14回 減らないSQLインジェクション脆弱性
- 第15回 減らないSQLインジェクション脆弱性
(解答編) - 第24回 無くならないSQLインジェクション脆弱性
今回はSQLインジェクションを復習してみたいと思います。
SQLインジェクションとは
SQLインジェクションはプログラマが意図しないSQL文を実行させる攻撃で、
- 直接SQLインジェクション
- 間接SQLインジェクション
直接SQLインジェクション
直接SQLインジェクションとはクエリ文字列、
攻撃例
"SELECT * FROM users WHERE username = '".$_GET['admin']."' AND password ='".$_GET['password']."';";
↓
SELECT * FROM users WHERE username = 'admin' AND password = '' OR 1=1;--';
間接SQLインジェクション
間接SQLインジェクションとは直接入力したデータを利用しないで、
攻撃例
Username: admin';--
Password: hogehoge
SELECT * FROM users WHERE username = 'admin';--' AND password = 'hogehoge';
ブラインドSQLインジェクション
前項までのように単純な直接SQLインジェクションや間接SQLインジェクションではなく、
ブラインドSQLインジェクションとはデータベース構造を知らずにSQL文を実行する攻撃手法です。SQLデータベースサーバ持つascii関数、
SQLインジェクション/ブラインドSQLインジェクションで可能な攻撃の例
- データベース構造の解析
(データベース名、 テーブル名、 フィールド名など) - データベースユーザの取得
- ファイルの読み書き
- コマンドの実行
- シェルの取得
- リモートシェルの取得
このような攻撃を自動化するツールも多数公開されています。別の機会でこのツールは紹介したいと思います。
最近のSQLインジェクションのセキュリティアドバイザリには、
下記の例では数値型ので入力を期待しており、
def generate_url(self, ascii):
return self.url +
"auktion_text.php?id_auk=1+and+1=1+and+ascii(substring((SELECT%20"
+ self.table_field + "%20FROM%20" + self.table_prefix +
"fh_user+WHERE+iduser=" + str(self.id) + "%20LIMIT%200,1)," +
str(self.charn) + ",1))%3E" + str(ord(ascii))
これらは典型的なMySQLサーバ用のブラインドインジェクション攻撃用コードです。下の例はURLを使ったブラインドインジェクションの行い方だけが例示されたケースですが、
SQLインジェクション対策
SQLインジェクション対策の基本はエスケープです。プリペアードクエリもSQLインジェクション防止に使えますが、
最近広く利用されているSQLiteなどでは数値型のデータ型がありません。入力バリデーションが甘いアプリ、
SQLインジェクション対策
- パラメータを全て文字列として取り扱いエスケープする
- SQL語句やテーブル、
フィールド名はホワイトリストでバリデーションする - 文字エンコーディングを厳格に取り扱い、
文字エンコーディング指定にはAPI (pg_ set_ client_ encoding, mysql_ set_ charset) を利用する - プリペアードクエリが利用可能な場合はプリペアードクエリを利用する
- 読み込み専用のアカウントも利用する
エスケープには必ずマルチバイト文字列に対応したデータベース専用のエスケープ関数pg_
パラメータをすべて文字列として取り扱った場合、
PHPに限らずデータベースアクセスを抽象化するライブラリのプリペアードクエリAPIは、
SQLインジェクションはコンテンツの改ざんにも利用されます。読み込みしか必要ないリクエストの処理に読み書き可能なアカウントでアクセスすることが常態化していませんか? セキュリティ対策の基本原則に
まとめ
紹介したブラインドSQLインジェクションが可能な脆弱性は
SQLインジェクションは非常に重大なセキュリティ上の問題です。しかし、
SQLインジェクションに脆弱なアプリは絶対に作らないよう注意しましょう。