以前の記事で、データからSQLインジェクションの影響などを紹介しました。
今回は、より具体的にSQLインジェクションの仕組みや種類、対策などを紹介していきます。
SQLインジェクション攻撃の仕組み
まずは簡単にSQLインジェクション攻撃の仕組みについて、説明していきます。
攻撃の流れは以下のとおりです。
1. 攻撃者が 脆弱性を含むWebアプリケーション
を見つける
2. Webアプリケーション上の入力フォームに 不正なSQL文
を入力し、送信する
3. データベースへ 不正なSQL文
が送られ、実行される
4. データベースからWebサイトへ、SQLの実行結果
が返ってくる
5. 実行結果を悪用し、攻撃者はデータベースに登録された会員情報を窃取をしたり、情報の改ざん・削除
などを行うことができる
SQLインジェクション攻撃の主な種類
1. インバンドSQLインジェクション
インバンドSQLインジェクションは、最も一般的なタイプの攻撃です。Webアプリケーションへの入力に対するレスポンスを収集し、データベースの脆弱性の有無を分析する攻撃手法です。
- UNIONインジェクション
- UNIONインジェクションは、UNION SQL演算子を悪用して、アプリケーションの正規のクエリ結果に追加のデータを組み込む攻撃手法です。この攻撃により、攻撃者はデータベース内の他のテーブルや列の情報を取得できます。
- エラーベースインジェクション
- エラーベースインジェクションは、データベースエラーメッセージを悪用して情報を引き出すSQLインジェクションの一種です。攻撃者は、意図的にエラーを発生させることで、データベースの内部情報を取得します。エラーメッセージにデータや構造に関する詳細が含まれる場合、それを利用してさらに攻撃を進展させます。
2. ブラインドSQLインジェクション
インバンドSQLインジェクションとは異なり、Webアプリケーションへの入力に対するレスポンスが明確にはありません。代わりに、悪意のあるユーザーは、Webアプリケーションの動作の変化を観察することで、データベースの状態を推測します。ブラインドSQLインジェクション攻撃は、完了までに時間がかかる場合があるため、インバンドSQLインジェクション攻撃ほど一般的ではありません。
- 時間ベースのブラインドSQLインジェクション
- 時間ベースのブラインドSQLインジェクションは、データベースの応答時間の遅延を利用して情報を引き出す手法です。攻撃者は、SQLクエリに意図的な待機処理を加え、アプリケーションの応答時間の変化を観察することで、条件の真偽を判断します。
- BooleanベースのブラインドSQLインジェクション
- 攻撃者がデータベースから情報を引き出す際に、True/Falseの応答を利用する攻撃手法です。直接的なデータの返却はなく、代わりにアプリケーションの動作や表示内容の変化を観察して、攻撃の成否を判断します。
3. アウトオブバンドSQLインジェクション
アウトオブバンドSQLインジェクションは、最も一般的でないタイプの攻撃です。アウトオブバンドSQLインジェクションは、データベースが即時に応答できない状況で、外部の通信チャネルを利用して情報を引き出す攻撃手法です。この攻撃では、データベースが直接的に応答しなくても、攻撃者が別の方法でデータを受信できるようにします。
SQLインジェクションの脆弱性を見つける
SQLインジェクションの脆弱性を見つけるには、ユーザー入力のポイントを調査し、悪意のあるペイロードを送信してシステムの反応を観察します。以下は、SQLインジェクションの脆弱性を見つけるための具体的な方法です。
ここでは3つの見つけ方を紹介していきます。
1. BurpSuiteなどを使い、手動で悪意のあるペイロードを送信し、見つける
2. SQLmapやsqlninjaなどの自動ツールを使い、さまざまなSQLインジェクションのパターンを一度にテストする
3. セキュリティベンダーに脆弱性診断を依頼する
項目 | 手動ペイロード送信 (BurpSuite等) | 自動ツール (SQLmap, sqlninja等) | セキュリティベンダーに脆弱性診断を依頼 |
---|---|---|---|
概要 | ユーザーがツールを使って直接ペイロードを注入し、アプリケーションの反応を観察する | 自動ツールが複数のペイロードを生成し、テストを自動で行う | プロのセキュリティエンジニアが診断を行い、脆弱性を特定し報告する |
精度 | 高い:カスタマイズしたテストが可能 | 高い:既知のペイロードを網羅的にテスト可能 | 非常に高い:専門的な知識と経験に基づくテストで、広範囲かつ詳細にわたる診断が可能 |
時間効率 | 低い:手動のため時間がかかる場合がある | 高い:自動で実行され、迅速に結果が得られる | 中程度:診断には数日~数週間かかることが多い |
コスト | 低コスト:ツールのライセンス料のみ | 低コスト:オープンソースのツールを使う場合は無料 | 高コスト:診断の範囲や内容により、費用が発生 |
脆弱性の深掘り | 得意:特定の脆弱性を深く解析可能 | 限定的:自動ツールは広範囲の検出に強いが、深い分析は手動が必要 | 得意:専門知識により、発見した脆弱性の詳細な分析やリスク評価が可能 |
操作の容易さ | 中程度:ツールの使い方やペイロードの理解が必要 | 高い:基本的なコマンドで実行可能 | 非常に高い:専門家が診断を行うため、ユーザー側での操作は不要 |
誤検知の可能性 | 低い:人間の判断に基づくため、誤検知が少ない | 中程度:ツールの自動解析による誤検知が発生する可能性あり | 低い:専門家による分析に基づくため、精度が高く、誤検知は少ない |
検出率 | 中~高:経験や知識に依存し、見落としの可能性あり | 高い:既知のペイロードを網羅的に試すため、高い検出率を誇る | 非常に高い:手動と自動の両方のテストを組み合わせたアプローチにより、全体的な検出率が高い |
- 手動ペイロード送信は、カスタマイズ性や特定の脆弱性の深掘りに優れ、特定の脆弱性を詳細に分析したい場合に適しています。
- 自動ツールは、効率的で迅速な脆弱性スキャンに最適で、短時間で広範囲の脆弱性を検出するのに役立ちます。
- セキュリティベンダーによる診断は、最も精密で信頼性の高い診断が可能で、特に大規模なシステムや深い分析が必要な場合に有効です。
状況に応じて、これらの方法を組み合わせて使用することで、より効果的な脆弱性検出が可能です。
SQLインジェクション攻撃の対策
SQLインジェクション攻撃の対策として、アプリケーションやデータベース設計において、入力の適切な処理
やクエリの安全な構成
が重要です。以下は、SQLインジェクションを防ぐための具体的な対策です。
1. パラメータ化されたクエリの使用
- SQL文の中で
動的な部分
をプレースホルダ(?
や:param
)に置き換え、ユーザー入力は変数として渡す
ことで、インジェクションを防ぎます。 - プレースホルダを使うことで、SQL文とユーザー入力が分離され、インジェクションのリスクが低減されます。
2. ORMの利用
- Django ORMやSQLAlchemyなどのORMは、データベースとやり取りする際に
自動でクエリのサニタイズ
を行い、インジェクション攻撃を防ぎます。 - ORMはSQLの生成を自動化し、構文エラーやインジェクション攻撃を防ぐための安全な構造を持っています。
3. 入力のバリデーションとサニタイズ
- ユーザー入力の内容を
想定される形式に合わせて検証(バリデーション)
し、不正な文字列やデータ型が入らないようにします。 - 入力されたデータが
文字列の場合、特殊文字(例:';--")をエスケープ
することで、不正なSQLコードの実行を防ぎます。
4. エラーメッセージの制限
- SQLエラーメッセージがユーザーに直接表示されると、データベースの情報が漏洩する可能性があります。エラーメッセージを
ユーザー向けにサニタイズ
し、デバッグ情報を含まない一般的なメッセージ
のみを表示します。 - 例:
"システムエラーが発生しました。管理者に連絡してください。"
5. Webアプリケーションファイアウォール(WAF)の導入
- WAFは、
不正なリクエストを検知・ブロック
するために有効です。WAFを導入することで、SQLインジェクションの試みを事前に防ぐことが可能です。 - ただし、WAFは
最終的な防御策
であり、アプリケーション自体のセキュリティ対策と併用することが望ましいです。
6. セキュリティテストの実施
- 定期的な
脆弱性診断や
自動スキャンツール(例: SQLmap)の活用
で、アプリケーションの脆弱性を検出し、早期に対処することが重要です。
7. ストアドプロシージャの活用
- ストアドプロシージャを使うことで、SQLクエリを事前に定義し、パラメータを変数として渡すことが可能になります。これにより、インジェクションのリスクを減少させます。
これらの対策を組み合わせることで、SQLインジェクションの脆弱性を効果的に防ぐことができます。
まとめ
- SQLインジェクション攻撃といっても複数の種類がある
- 対策として、設計開発フェーズでできること、運用フェーズでできることがあり、複数の対策を組み合わせることが重要