Webアプリケーション:最も露出した攻撃面

T1190 公開アプリケーションの悪用

インターネットに公開された Web アプリケーションは、企業のファイアウォールを迂回して内部のデータベースやビジネスロジックに直接アクセスできる、世界最大の攻撃面です。企業がどんなに境界防御を固めても、HTTPSポート(443)は正規のトラフィックとして常に開放されています。

非営利団体 OWASP が数年ごとに更新する**OWASP Top 10**は、開発者が知っておくべき重大な脆弱性のランキングです。20年以上にわたり、以下の3つの脆弱性が形を変えながら上位に居続けています。これは「古い問題が解決されていない」というより、「Webが進化するたびに同じ構造的欠陥が新しい文脈で現れる」ことを意味しています。

学習目的の注意事項

本レッスンで解説するエクスプロイト手法は、防御アーキテクチャの設計に必要な「攻撃者の視点」を学ぶためのものです。所有権または明示的な許可のないシステムへの攻撃試行は、いかなる理由であれ不正アクセス禁止法違反となります。


SQLインジェクション(SQLi):データソースの完全陥落

データベースへの問い合わせを行うSQL文に、**「データの一部として見せかけた悪意のあるコマンド」**を混入させ、強制的に実行させる攻撃です。一度成立すれば、顧客情報の全件ダンプ(情報漏洩)から、データベースサーバー自体のコード実行(RCE)まで至る、最も破壊的な脆弱性の一つです。

脆弱な実装とインジェクションの成立

// 脆弱なコード(レガシーシステムで頻出する文字列の直接結合)
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '" . $username . "'";

攻撃者が $username' OR '1'='1 を入力すると、バックエンドで以下のSQLが構築・実行されます。WHERE句の条件が常に「真(True)」になるため、全ユーザーのデータが漏洩します。

SELECT * FROM users WHERE username = '' OR '1'='1'

ポイントは、これが「バグ」ではなく「SQLの仕様どおりの動作」である点です。文字列結合でSQLを組み立てると、ユーザー入力がデータではなくコマンドとして解釈される余地が生まれます。

ブラインドSQLインジェクション(Blind SQLi)

現代のWebアプリはエラー画面にSQL文法エラーをそのまま表示しません。しかし攻撃者は、クエリに SLEEP(10) などの遅延コマンドを忍ばせ、「レスポンスが10秒遅れたからこの推測はTrueだ」と1文字ずつデータを抜き出す時間ベースのブラインド攻撃を、SQLmap などの自動化ツールで実行します。エラーが出なくても安全ではありません。

根本的な防衛策:プリペアドステートメント

WAFによるシグネチャ検知は「既知のパターン」を弾くだけで、難読化された攻撃は通過します。唯一の根本的な解決策は、コードレベルでの**プリペアドステートメント(パラメータ化クエリ)**の確実な実装です。

// プリペアドステートメント:SQLの「構文」と「データ」を完全に分離する $stmt = $pdo->prepare(“SELECT * FROM users WHERE username = :username”);

// ユーザー入力は純粋な「データ」としてのみバインドされ、決してSQLコマンドとして解釈されない $stmt->execute([‘username’ => $username]); $user = $stmt->fetch();


クロスサイトスクリプティング(XSS):ブラウザのハイジャック

SQLi が「サーバー(データベース)」への攻撃であるのに対し、XSS は「他のユーザーのブラウザ(クライアント側)」への攻撃です。攻撃者が仕込んだ悪意のある JavaScript が、被害者のブラウザ上で「正規のサイトの一部」として実行されます。これにより、セッションCookieの窃取、偽ログイン画面の表示、ユーザーの権限を使った不正操作が可能になります。

XSSの3つの主要カテゴリ

カテゴリ攻撃のメカニズム主な発生箇所
反射型(Reflected)攻撃者がスクリプトを埋め込んだ罠URLを被害者に踏ませ、サーバーがそれをそのまま画面に「反射」して出力することで発火する。検索結果ページ、エラーメッセージ表示画面。
蓄積型(Stored)攻撃者がDBにスクリプトを保存(投稿)し、そのページを閲覧した全員のブラウザで被害が連鎖的に発火する。最も危険。コメント欄、プロフィール画面、掲示板。
DOMベースサーバーを介さず、フロントエンドのJavaScript内でのDOM操作の欠陥(innerHTML への直接代入など)によって、ブラウザ内だけで完結して発火する。SPA(Single Page Application)のURLフラグメント処理など。

蓄積型は「一度仕込めば閲覧した全ユーザーが被害を受ける」ため、特に危険度が高いカテゴリです。大規模なコメントサイトやECサービスで発生すると、被害が数万〜数十万ユーザーに及ぶことがあります。

現代のXSS防御アーキテクチャ

  1. コンテキストに応じた出力エスケープ: ユーザー入力をHTMLとして出力する際、<> などの特殊文字を無害化します。React、Vue などの現代のフレームワークは標準でエスケープ処理を行いますが、dangerouslySetInnerHTML などの抜け穴の使用には最大限の警戒が必要です。
  2. CSP(Content Security Policy): 「このドメインからロードされたスクリプト以外はブラウザで実行させない」と HTTP ヘッダーでブラウザに強制する、最も強力な XSS の防波堤です。コード側に脆弱性があっても、スクリプトの発火をブラウザレベルでブロックできます。
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;

CSRF(クロスサイトリクエストフォージェリ):権限の「無断借用」

CSRFは、被害者が「あるサービス(例:銀行サイト)にログインした状態」で別の悪意のあるサイトを開いた瞬間、背後で勝手に「銀行への送金リクエスト」を送信させる攻撃です。

仕組みを理解するカギはブラウザの仕様にあります。ブラウザは「同じドメイン宛てのリクエストには、そのドメインの Cookie(セッション情報)を自動で付与する」という動作をします。攻撃者はこれを逆手に取り、悪意のあるサイトから銀行のAPIに向けたリクエストを被害者のブラウザに送らせます。被害者の Cookie が自動で付与されるため、銀行側には「正規のユーザーからのリクエスト」に見えてしまいます。

CSRFを無効化する2つのアプローチ

かつては「推測不可能なワンタイムトークン(CSRFトークン)」を隠しフィールドに埋め込む手法が主流でした。現在ではブラウザの Cookie 仕様の進化により、より根本的な防衛線が使えるようになっています。

Set-Cookie: session_id=abc123xyz; Secure; HttpOnly; SameSite=Lax

// SameSite=Lax(現在のブラウザのデフォルト): 外部サイトからのPOSTリクエスト等にはCookieを付与しない。 // SameSite=Strict: 外部サイトからのいかなるリンク遷移でもCookieを付与しない(最も強力)。

SameSite=Lax でほとんどの CSRF は防げますが、レガシーブラウザのサポートや複雑な認証フローを持つシステムでは、CSRFトークンも組み合わせた多層防御が推奨されます。


理解度チェック

【確認問題】Webフロントエンド開発において、第三者が注入した悪意のある JavaScript がブラウザ上で実行される「XSS(クロスサイトスクリプティング)」を根本的に防ぐための、HTTPレスポンスヘッダー設定として最も強力なものはどれですか?