本シリーズでは、Webアプリケーションの脆弱性を突く攻撃について順に解説します。解説する脆弱性は、IPAが提供している「安全なウェブサイトの作り方」で紹介されている11の脆弱性に準拠しています。安全なウェブサイトの作り方」は、開発者や管理者向けの、セキュリティガイドラインとベストプラクティスを纏めたものです。
- SQLインジェクション
- OSコマンド・インジェクション
- パス名パラメータの未チェック/ディレクトリ・トラバーサル
- セッション管理の不備
- クロスサイト・スクリプティング(XSS)
- CSRF(クロスサイト・リクエスト・フォージェリ)
- HTTPヘッダ・インジェクション
- メールヘッダ・インジェクション
- クリックジャッキング
- バッファオーバーフロー
- アクセス制御や認可制御の欠落
本記事では、インジェクション系に関する脆弱性を見ていきます。その中でも、まずは以下の3つをピックアップします。
- SQLインジェクション
- OSコマンド・インジェクション
- クロスサイト・スクリプティング(XSS)
第2回では、残りのインジェクション系の脆弱性である、HTTPヘッダ・インジェクション、メールヘッダ・インジェクションの2つを見ていきます。
インジェクション系の脆弱性
インジェクション系の脆弱性は、悪意のあるユーザーがアプリケーションに対して不正なコードを挿入することで、アプリケーションの挙動を操作したり、機密情報を盗み出したりする脆弱性の総称です。これらの脆弱性は主に以下のような特徴を持っています。
- 不正な入力の受け入れ: 攻撃者はアプリケーションに不正なデータを送信します。これは、フォーム、URLパラメータ、クッキー、HTTPヘッダーなど、さまざまな入力経路を通じて行われる可能性があります。
[例: SQLインジェクション、OSコマンドインジェクション] - 外部からのコード実行: 攻撃者が不正なコード(SQLクエリ、スクリプト、OSコマンドなど)を注入することにより、アプリケーション内でそのコードが実行される可能性があります。これにより、データベースの操作、セッションのハイジャック、機密情報の漏洩などが起こり得ます。
[例: XSS、LDAPインジェクション] - 信頼されていないデータの処理: アプリケーションが外部からの入力データを信頼している場合、攻撃者はそれを悪用して不正な操作を行うことができます。信頼されていないデータに対する適切なバリデーションやサニタイズの欠如が、この脆弱性の一因となります。
[例: HTTPヘッダ・インジェクション] - 機密情報の漏洩: インジェクション攻撃が成功すると、攻撃者はアプリケーション内の機密情報にアクセスできる可能性があります。これには、データベース内の個人情報、認証情報、セッションIDなどが含まれます。
[例: SQLインジェクション、メールヘッダ・インジェクション]
これらの脆弱性は、適切なセキュリティ対策が講じられない限り、深刻なセキュリティリスクとなります。そのため、適切な入力バリデーション、エスケープ処理、アクセス権の制限、セキュリティポリシーの実装などの対策が必要です。
では、次の3つのインジェクション系の脆弱性についてもう深掘りしていきます。
- SQLインジェクション
- OSコマンド・インジェクション
- クロスサイト・スクリプティング(XSS)
SQLインジェクション
まずはSQLインジェクションです。SQLインジェクションは、悪意のあるユーザーがアプリケーションの入力フォームやURLパラメータなどに不正なSQLクエリを挿入することで、データベースに対して攻撃を行う手法です。これにより、攻撃者はデータベースに予期しない操作を実行したり、機密情報を盗み出したりすることができます。
SQLインジェクションの被害は以下のものが考えられます。
- データベースの改ざん: 攻撃者が不正なSQLクエリを送信し、データベース内のデータを改ざんします。これにより、データの消去や改竄、不正なデータの挿入などが行われる可能性があります。たとえば、ユーザーの認証情報が改ざんされると、認証制御が無効化され、不正なアクセスが可能になります。
- 機密情報の漏洩: SQLインジェクションによって攻撃者がデータベースから機密情報を抽出することができます。個人情報、クレジットカード情報、パスワードなどの機密データが盗まれる可能性があります。これにより、個人のプライバシーが侵害されたり、金銭的な被害が発生したりする可能性があります。
- データの破壊: SQLインジェクションによって攻撃者がデータベース内のデータを削除することができます。重要なデータが失われることで、ビジネスプロセスやサービスの停止、復旧に関連する費用が発生する可能性があります。
- サーバーのリソースの乱用: SQLインジェクションによって攻撃者が大量のSQLクエリを送信することができます。これにより、データベースサーバーのリソースが枯渇し、サービスの遅延やダウンが発生する可能性があります。
SQLインジェクションの攻撃手法
SQLインジェクションは、アプリケーションがユーザーからの入力に対して、適切なエスケープやサニタイズを行わず、直接SQLクエリに組み込むことが原因です。例えば、ログインフォームにおいて、ユーザーがユーザー名とパスワードを入力し、以下のようなSQLクエリが実行される場合を考えます。
SELECT * FROM users WHERE username='$username' AND password='$password'
攻撃者は、パスワード欄にOR 1=1 --
という文字列を入力することで、次のようなSQLクエリが実行されるように仕向けます。
SELECT * FROM users WHERE username='' OR 1=1 --' AND password=''
このクエリでは、1=1
は常に真であるため、全てのユーザーが認証されることになります。
SQLインジェクションの対策
対策としては以下のものが上げられます。
- プリペアドステートメントの使用: プリペアドステートメントを使用することで、SQLインジェクション攻撃を防ぐことができます。プリペアドステートメントを使用すると、SQLクエリに変数を埋め込む際に適切にエスケープされるため、不正なSQLが注入されることを防ぐことができます。
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
入力値のサニタイズ: ユーザーからの入力を受け取る際に、適切なサニタイズ(特殊文字のエスケープなど)を行うことで、不正なSQLが実行されるのを防ぐことができます。
$username = mysqli_real_escape_string($connection, $_POST['username']);
$password = mysqli_real_escape_string($connection, $_POST['password']);
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
OSコマンド・インジェクション
OSコマンド・インジェクションは、アプリケーションがユーザーからの入力を適切に検証せずに、OSコマンドとして実行することで発生します。攻撃者は不正なOSコマンドを入力することにより、サーバー上で任意のコマンドを実行することができます。その結果、システムやデータのセキュリティが脅かされ、機密情報が漏洩したり、システムが破壊される被害が発生します。
具体的な被害には以下のものが考えられます。
- サーバー上で任意のコマンドを実行されることによるシステムの乗っ取りや情報漏洩
- ファイルの削除や改ざんによるデータの損失やセキュリティ侵害
- ネットワーク上での攻撃(例: ポートスキャンやDDoS攻撃など)の実行
- サーバーのリソース乱用によるサービスの停止やダウン
OSコマンド・インジェクションの攻撃手法
あるWebアプリケーションでは、ユーザーがファイル名を指定してサーバー上にファイルを生成する機能が提供されているとします。ユーザーはファイル名を入力し、アプリケーションはその名前でファイルを生成します。この際、入力値を適切に検証せずに、そのままOSコマンドとして実行してしまうと、OSコマンド・インジェクションの脆弱性が生じる可能性があります。
例えば、以下のコマンドがファイル名として入力された場合を考えます。
'; cat /etc/passwd > malicious_file.txt; '
この場合、アプリケーションは入力値をそのままOSに渡し、以下のコマンドが実行されます。
cat /etc/passwd > malicious_file.txt
このコマンドは、/etc/passwd
ファイルの内容を読み取ってmalicious_file.txt
に書き込むものです。攻撃者はこのファイルを後でダウンロードし、機密情報を盗み出すことができます。
OSコマンド・インジェクションの対策
OSコマンド・インジェクションを防ぐためには、入力値の信頼性を確認し、適切なエスケープや検証を行うことが重要です。
- 入力値のサニタイズ: ユーザーからの入力を適切にサニタイズすることで、不正なコマンドを無害な文字列に変換することができます。
- ホワイトリスト(正規表現)の使用: 入力値を事前に定義された許可された文字列や形式のみに制限することで、不正なコマンドの実行を防ぐことができます。
クロスサイト・スクリプティング(XSS)
XSSは、悪意のあるスクリプトをウェブアプリケーションに注入し、そのスクリプトが他のユーザーによって実行されることで発生します。
具体的な被害には以下のものが考えられます。
- セッションハイジャック: 攻撃者がユーザーのセッションクッキーを盗み、そのセッションを乗っ取ります。
- 情報盗み出し: 攻撃者がユーザーのクッキーや個人情報を盗み出し、機密情報を入手します。
- アカウント乗っ取り: 攻撃者が悪意のあるスクリプトを使用して、ユーザーのアカウントを乗っ取ります。
- 悪意のあるリダイレクト: 攻撃者がユーザーを悪意のあるウェブサイトにリダイレクトします。
- ウェブサイトの改ざん: 攻撃者がウェブサイトのコンテンツを改ざんし、偽の情報を表示します。
クロスサイト・スクリプティング(XSS)の攻撃手法
<form action="http://www.kmotojim.com/example.txt" method="GET">
<input type="text" name="query">
<input type="submit" value="Search">
</form>
このHTMLは、ユーザーが入力した内容をURLパラメータとしてページに表示します。例えば、以下のような不正な入力を行うことで、スクリプトが実行されます。
<script>alert('XSS攻撃が実行されました');</script>
こちらを試していただいて、「上記をフォームに入力して送信すると、ページ上にアラートが表示されます。」と言いたいところなのですが、私達が普段利用しているブラウザでは、セキュリティ対策としてエスケープ処理が既に組み込まれており、このようなスクリプトは実行されてない仕組みとなっております。
クロスサイト・スクリプティング(XSS)の対策
XSS攻撃を防ぐためには、入力データをエスケープまたはサニタイズし、信頼できる形式で出力することが重要です。
- HTMLエスケープの使用: サーバーサイドで入力データをエスケープして出力することで、悪意のあるスクリプトを無害なテキストとして扱います。
- CSP (Content Security Policy)の実装: CSPを使用することで、ブラウザが実行可能なスクリプトのソースを制限し、XSS攻撃を防ぐことができます。
- XSSフィルタリングの使用: サーバーサイドやブラウザ側でXSSフィルタリングを実装することで、悪意のあるスクリプトを検出し、ブロックすることができます。
おわりに
本記事では、Webアプリケーションのインジェクション系の脆弱性について説明しました。攻撃の入り口は違いますが、その手法と対策には共通項がある、ということが伝わりましたら幸いです。
次回は、インジェクション系の後半(HTTPヘッダ・インジェクション、メールヘッダ・インジェクション)です。
Webアプリケーション攻撃入門記事の一覧ページはこちらです。