なぜPHPアプリにセキュリティホールが多いのか?
第6回 意外に知られていないブラインドSQLインジェクション
前回の記事でSQLインジェクションの話は終わりにして,クロスサイトスクリプティングの話を書かせて頂こうと思っていました。しかし,6月5日に東京にて開催されたPostgreSQLカンファレンス2007でセキュリティをテーマに講演させて頂き,意外にブラインドSQLインジェクションをご存じでない方が沢山いらっしゃいました。40名ほどの聴講者の皆様にSQLインジェクションをご存じの方?とお聞きするとほぼ全ての方が知っていると答えたのですが,ブラインドSQLインジェクションをご存じの方は数名でした。
SQLインジェクションの常識
ブラインドSQLインジェクションの話をする前に,SQLインジェクションとその対策の常識について確認します。
SQLインジェクション対策として間違ってはいないが不十分な対策
- エラーメッセージを表示しない(特にSQLエラー)
- ユーザ入力文字列をエスケープする
これらはSQLインジェクション対策として有用な対策ですが,十分な対策ではありません。この連載でも解説済みですが,SQLインジェクションを確実に防ぐには,全てのクエリにバインドメカニズム(ストアドプロシージャ)を利用する,すべての変数を文字列として処理しエスケープするの2種類の対策があります。
これらの対策を行っても,1ヶ所でもブラインドSQLインジェクションによって攻撃可能である場合,データベース全体のデータを盗まれたり,改ざんされる危険性があります。
以下はよくあるSQLインジェクションの脅威に対する誤解です。
- データベースの構造を知られていなければ攻撃できない
- エラーメッセージを表示しなければSQLインジェクションによって攻撃されない
- SQLインジェクションを成功させるには高度な攻撃スキルが必要である
これらは全てとても危険な誤った認識です。
ブラインドSQLインジェクション
PostgreSQLカンファレンスの私のセッションをお聞きになられた方は,デモによりいかに簡単にブラインドSQLインジェクションが可能か理解いただけたと思います。
ブラインドSQLインジェクションを利用した攻撃手順
- SQLインジェクションに脆弱な箇所を見つける
- フィンガープリンティングによりSQLデータベースサーバの種類を判別する
- ブラインドSQLインジェクションを行い,データベースの構造を解析する
- 攻撃用のSQL文を実行させ,情報の不正取得や改ざんを行う
まず,SQLインジェクションに脆弱な部分を発見するのは比較的簡単です。例えば,レコードIDの入力が可能な箇所を探すには,ID番号の代わりに
1 AND 1 = 1
や
1 OR 1 = 1
のような文字列を送信してアプリケーションの動作がどのように変化するか観察するとSQLインジェクションに脆弱か判別できます。これ以外にもSQLインジェクションに脆弱かチェックするために便利な文字列はいくつもあります。エラーメッセージが表示されなくてもプログラムの動作はSQL文の実行結果によって変化します。プログラムが予期していない入力を与えることによって発生するアプリケーションの動作の違いによって攻撃者が簡単にSQLインジェクションに脆弱か判別できます。
データベースサーバの種類もフィンガープリンティングによって簡単に判別できます。ステップ1でSQLインジェクションに脆弱な箇所がわかっているので,その脆弱性を利用してDBMS特有の関数が利用できるか調査します。例えば,MySQLを利用している場合はbenchmark()関数が利用でき,PostgreSQLの場合はpg_sleep()関数が利用できるかチェックすることによりデータベースサーバの種類が判別できます。
次にブラインドSQLインジェクションを行ってデータベースを解析します。ブラインドSQLインジェクションにはデータベースシステムのシステムカタログ(テーブル定義などを保存したシステムデータベース)をクエリしてテーブル名やフィールド名を解析します。
SQL Serverのフィールド名を取得
SELECT name FROM syscolumns
WHERE id =(SELECT id FROM sysobjects
WHERE name = 'tablenameforcolumnnames')
PostgreSQLのテーブル名を取得
SELECT tablename FROM pg_tables WHERE schemaname= 'public'
詳しい解説は省略しますが,ブラインドSQLインジェクションが可能な場合,テーブル名,フィールド名,データ型などデータベース定義全体を解析できます。
最後に解析したデータベースの設計情報とSQLインジェクション脆弱性を利用して,目的のデータを盗んだり,改ざんします。データベース構造がわかっているので,SQLインジェクション攻撃を成功させるのはそれほど難しいことではありません。
SQLインジェクション脆弱性は非常に危険
すべてのSQLインジェクション脆弱性がブラインドSQLインジェクションに利用できるわけではありませんが,SQLインジェクション脆弱性の多くがブラインドSQLインジェクションを許してしまいます。SQLインジェクション対策は非常に簡単ですが,作ってしまうと非常に危険な脆弱性であることを,Webサイト運営者と開発者は理解していなければなりません。
参考URL
- SQL Injection Cheatsheet
- http://ferruh.mavituna.com/makale/sql-injection-cheatsheet/
- Blind SQL Injection (PDF)
- http://www.spidynamics.com/whitepapers/Blind_SQLInjection.pdf
なぜPHPアプリにセキュリティホールが多いのか?
- 第46回 セキュリティ対策を考える上で欠かせないコンテクスト
- 第45回 入力バリデーションはセキュリティ対策
- 第44回 セキュリティ対策が確実に実施されない2つの理由
- 第43回 PHP 5.3のcrypt関数の問題
- 第42回 PostgreSQL 9.0に見るSQLインジェクション対策
- 第41回 PHP 5.3.4におけるセキュリティ上重要な仕様変更
- 第40回 MOPS:安全性の高いパスワードハッシュ作成ツール - phpass
- 第39回 MOPS:静的PHPソースコード脆弱性スキャナ RIPS
- 第38回 MOPS:PHPにおけるコード実行(2)
- 第37回 MOPS:PHPにおけるコード実行(1)
-
Webアプリセキュリティ対策入門〜あなたのサイトは大丈夫?
本書は,Webサイトのセキュリティ確保のために必要な基礎知識と,安全なコードを書くために必要な基礎知識を解説しています。Webアプリケーションは比較的簡単に作成で...
-
はじめてのPHP言語プログラミング入門
Webアプリケーション構築ツールとしてPHPを取り上げた書籍は数多くありますが,言語の解説・入門書としての書籍はあまりありません。 本書は,プログラミング言語として...
-
SQL Injection
[PR] ږ Web Application SQLインジェクション 不正なSQL文を注入して重要情報の取得や改竄(かいざん)を行うことが可能となる脆弱性、または攻撃のことです。 検証 ウェブアプリケーションのログイン画面において、以下のような実装(Java)がされていると...
Tracked : #1 情報セキュリティ ポータルサイト (PukiWiki/TrackBack 0.4) (2008/03/23, 03:17)

