SQLインジェクション(SQLi)攻撃とその防止策

Risk Factors

Likelihood

Complexity

Business Impact

SQLインジェクション(SQLi)

SQLインジェクション(SQLi)

とは SQLインジェクションは、データベースを侵害できる一般的なハッキング技法です。SQLコマンドまたはコードの断片を正当なデータ入力フィールド(パスワードのフィールドなど)に「注入」することにより、攻撃者はSQLを使用してデータベースと直接通信することができます。こうした技法がうまく機能するのは、SQLがコントロール・プレーンとデータ・プレーンを区別しないからです。悪用に成功すると、データベースの機密データを共有させ、データを変更し、データベースに対して管理操作(例:Db2などのDBMSのシャットダウン)を実行して、DBMSファイル・システムに存在する特定のファイルの内容を復元し、さらにはオペレーティング・システムに対してコマンドを発行することもできます。SQLiは一種のコード・インジェクション攻撃です。


SQLi攻撃に対する防御

SQLインジェクション攻撃を防御する方法についていくつか説明します。

  1. パラメータ化されたクエリを使用し、ユーザが送信した入力を検証して、ストアド・プロシージャを使用する
  2. 動的SQLを避ける
  3. 悪意のある既知の入力をブロックする
  4. 入力をサニタイズする データベースに対するクエリの実行方法を制限することによって、攻撃者が利用する抜け穴を塞ぐことができます。データベースに影響を及ぼす可能性のある文の種類を制限することによって、ストアド・プロシージャがSQLインジェクション攻撃に対処できるようになります。一つのアプローチは、安全な値のリスト(別名、ホワイトリスト)からの文字だけを受け入れることによる厳格な入力検証を行うことです。もう一つのアプローチは、悪意のある可能性のある値のリスト(別名、ブラックリスト)に一致する入力をすべて拒否することです。承認済みのエントリ以外はすべてブロックするのが非常に効果的ですが、実行が困難であるだけでなく、継続的なメンテナンスも必要です。悪意のある入力をブロックしようと試みるのは、一般に効果のない技法と考えられています。悪意のあるコードを探すフィルタをすり抜ける方法がたくさんあるからです。たとえば、攻撃者は以下のことが可能です。
  • 大文字と小文字を使用して、大文字と小文字を区別するフィルタを回避する
  • エスケープ文字を使用してフィルタを回避する
  • 異なる種類のエンコードを使用して検知を回避する

こうした種類の防衛手段を試し、回避するために使用される方法は多数ありますが、これらはそのごく一部です。この攻撃の検知は復号を使用することで強化できます。SQLインジェクション攻撃が、通常は、TLSなどの暗号化プロトコルを使用するHTTPSの443番ポート経由で発生するからです。さらに、復号されたSQLトラフィックをSQLインジェクション型の攻撃の検知に使用できます。そのため、TLS 1.3やKerberosをはじめとする一般的な暗号化プロトコルのすべてに対応した復号機能が、セキュリティ・ツールに搭載されていることが重要です。


SQLインジェクションの歴史

SQLインジェクションに関する情報が文書として提供されたのは、1998年12月にオンライン・マガジンのPhrackに投稿されたJeff Forristal氏(別名Rain Forrest Puppy)による記事が最初とされています。その当時、Forristal氏はWindows NTサーバのハッキング方法に関する記事を書いており、特定のコマンドを入力することによってあるサーバからの情報共有が強制的に停止されることを発見しました。その最初の公開から15年後、SQLiは依然として脆弱性の上位に位置付けられています。