資格道場 › レッスン一覧 › セキュリティ
セキュリティ・16/23・10分

Webアプリケーションへの攻撃と対策

ゴール

SQLインジェクション・クロスサイトスクリプティング(XSS)・ディレクトリトラバーサル・セッションハイジャック・オープンリダイレクトについて、説明文から攻撃名を選べるようになる。攻撃と対策の正しい組合せも選べるようになる。

Webアプリへの攻撃は「攻撃名と説明」「攻撃と対策」を入れ替えた選択肢で毎年のように出題され、対応を覚えていれば数秒で解ける得点源です。要件定義で「入力値はプレースホルダで扱う」といった非機能要件を書くときにも、そのまま使える知識です。

このレッスンで稽古する(用語チェック・過去問)

結論:攻撃は「どこで悪さをするか」で見分ける

このレッスンの攻撃は、悪い入力がどこで命令として解釈されるかで区別できます。データベースならSQLインジェクション、利用者のブラウザならXSS、サーバのファイルの場所ならディレクトリトラバーサルです。対策は「その場所で特別な意味を持つ文字を、ただの文字として扱わせる」が基本になります。

攻撃 悪い入力が解釈される場所 被害 代表的な対策
SQLインジェクション データベース(SQL文) データの不正取得・改ざん・削除 プレースホルダ/SQLの特殊文字のエスケープ
クロスサイトスクリプティング(XSS) 利用者のWebブラウザ(HTML) スクリプトの実行・情報漏えい 画面に出すときにHTMLの特殊文字をエスケープ
ディレクトリトラバーサル サーバのファイルの場所(パス名) 非公開ファイルの閲覧 外部からの値でファイル名を直接指定しない
セッションハイジャック ログイン状態を示すセッションID なりすまし ログアウト時にサーバ側でIDを無効化・重要操作前の再認証
オープンリダイレクト 自動転送(リダイレクト)機能 偽サイトへの誘導 転送先を制限する
flowchart LR
  A["攻撃者の入力"] --> B["Webアプリ"]
  B --> C["データベース:SQLインジェクション"]
  B --> D["利用者のブラウザ:XSS"]
  B --> E["サーバのファイル:ディレクトリトラバーサル"]

SQLインジェクション:いちばんよく出る

定義・エスケープ・プレースホルダを合わせた出題数は、本試験系(8回)・免除試験(19回)のどちらでも、このレッスンの中でいちばん多いです。SQLインジェクションとは、Webアプリの入力欄に悪意のある文字列を入れ、アプリが組み立てるSQL文(データベースへの命令文)の意味を書き換える攻撃です。結果として、データベースのデータが不正に取得・改ざん・削除されます。

たとえるなら、役所の申込書の「氏名」欄に「山田太郎。ついでに金庫を開けよ」と書いたら、係員が後半を命令として実行してしまう状態です。原因は、入力された値と命令文の区別がついていないことにあります。過去問の正解文は「Webアプリケーションに問題があるとき」「データ操作言語の呼出し方に不備がある場合」で始まり、「データベースのデータの不正な取得・改ざん」で終わる形がほとんどです。

対策は2つあり、試験ではどちらも正解になります。

対策 中身 過去問での言い回し
エスケープ処理 入力中の、SQLで特別な意味を持つ文字(' など)を無害な文字に置き換える 「特別な意味をもつ文字として解釈されないようにする」
プレースホルダ SQL文の形を先に固め、入力値は後から「値」としてはめ込む 「プレースホルダを使って命令文を組み立てる」「静的プレースホルダを使用する」

エスケープも、試験では単独で正解の対策として出ています。実務では、根本的な対策はプレースホルダです。エスケープは1か所でも処理が漏れると効かないため、漏れに弱いという違いがあります。プレースホルダは、記入欄の位置が決まった申込書のようなもので、欄に何が書かれていても「値」としてしか扱われません。

入力と命令の区別がつくか区別がない(SQLインジェクション)氏名欄:山田太郎。ついでに金庫を開けよ係員が後半を命令として実行してしまうプレースホルダ:欄の位置が決まった申込書① SQL文の形を先に固める② 入力は後から「値」としてはめ込む何が書かれていても値としてしか扱われない
入力と命令文の区別がないと入力の後半が命令として実行され、プレースホルダなら入力はただの「値」として扱われる。

クロスサイトスクリプティング(XSS):免除試験で頻出

クロスサイトスクリプティング(XSS)とは、脆弱なWebサイトを経由して、攻撃者のスクリプト(ブラウザで動く小さなプログラム)を閲覧者のブラウザで実行させる攻撃です。原因は、入力されたデータをそのまま画面に出してしまうことです。出題は免除試験だけ(定義6回・対策4回)ですが、SQLインジェクションの問題で誤答として必ず並びます。

種類 スクリプトの届け方 見分けるキーワード
反射型XSS 罠のリンクをクリックさせ、スクリプト入りのリクエストを送らせる。レスポンスに埋め込まれて実行される 「罠を仕掛けたWebページ」「リンクをクリック」
格納型XSS 掲示板などに書き込んでサーバに保存させ、後から閲覧した人のブラウザで実行される 「掲示板に書込み」「その後に閲覧した利用者」

対策は、入力データを画面に出すときに、HTMLで特別な意味を持つ文字(< や > など)をエスケープし、HTMLタグとして解釈されないようにすることです。SQLインジェクションのエスケープと似ていますが、守る相手が「データベース」ではなく「HTML(ブラウザ)」です。OSへのパッチ適用や入力サイズの制限では、XSSは防げません。

スクリプトはどこで動くか攻撃者:スクリプト入りの入力脆弱なWebサイト入力されたデータをそのまま画面に出す閲覧者のブラウザスクリプトが実行される対策:画面に出すときにエスケープ< や > などをただの文字にするHTMLタグとして解釈されない
XSSでは、攻撃者のスクリプトが脆弱なWebサイトを経由し、閲覧者のブラウザで実行される。対策は画面に出すときのエスケープ。

CSRFとの違い:XSSと混同させる定番

**CSRF(クロスサイトリクエストフォージェリ)**とは、罠のページを見た利用者に、別のWebサイトで本人が意図しない操作(送金や書込みなど)をさせる攻撃です。XSSが「ブラウザでスクリプトを動かす」のに対し、CSRFは「ログイン中の本人として勝手に操作させる」点が違います。SQLインジェクションの問題では「別のWebサイトで,訪問者が意図しない操作を行わせる」という選択肢がCSRFのひっかけです。

ディレクトリトラバーサル:本試験でも出る

ディレクトリトラバーサルとは、入力値からファイル名を組み立てるアプリに、上位のフォルダを指す文字列「../」を入れ、非公開のファイルを閲覧する攻撃です。本試験系3回・免除6回と、XSSより本試験での出題が多い知識です。正解文には「パス名を使ってファイルを指定」「上位のディレクトリを意味する文字列」が入ります。

対策は、外部から受け取った値でサーバ内のファイル名を直接指定しないこと、「../」を含む入力を受け付けないことです。この2つは、SQLインジェクション対策を問う問題で誤答の選択肢として登場しています。

「../」で上位のフォルダへ上がる上位のフォルダ公開フォルダ非公開ファイル公開ファイル../本来の範囲入力値からファイル名を組み立てると非公開のファイルを閲覧される
入力に「../」を入れると公開フォルダから上位のフォルダへ上がり、非公開のファイルまで届いてしまう。

セッションハイジャック対策:出題は免除試験の2回だけ

セッションハイジャックとは、ログイン状態を表すセッションID(サーバが利用者ごとに発行する通し番号のような値)を盗み、本人になりすます攻撃です。過去問は免除試験で2回、どちらも対策を問う形でした。正解は次の2つです。

  • ログアウト時に、Webサーバ側でセッションIDを無効にする(盗まれたIDが使えなくなる)
  • 重要な情報を表示する直前に、パスワードで再認証する(乗っ取られても被害を広げない)

通信の暗号化や、IDをcookieやURLに入れるといった「IDの持たせ方」の変更は、乗っ取られた後の被害を防ぐ対策として不正解です。利用者ごとに固定のセッションIDを使うのは逆効果で、誤答として出ています。

盗まれたセッションIDを使えなくするログイン → サーバがセッションIDを発行攻撃者がセッションIDを盗む盗んだIDで本人になりすます対策ログアウト時にサーバ側でIDを無効化盗まれたIDが使えない重要な情報の表示直前にパスワードで再認証被害を広げない
盗まれたセッションIDでなりすまされる流れと、正解になる2つの対策が効く場所。

オープンリダイレクト:1問だけ

オープンリダイレクトとは、アクセスすると別のサイトへ自動で転送する機能を悪用し、攻撃者が指定した偽サイトへ誘導する攻撃です。正規サイトのURLから偽サイトへ飛ぶので、利用者が気づきにくい点が狙いです。偽のURLを直接リンクに書くHTMLメールのフィッシングとは、「正規サイトの転送機能を使うかどうか」で見分けます。

試験での問われ方:攻撃と対策の入れ替え

出題パターンは2つです。1つは「攻撃の説明を選ぶ」問題で、他の攻撃の説明が誤答に並びます。もう1つは「攻撃と対策の組合せを選ぶ」問題で、別の攻撃の対策を入れ替えて並べます。

選択肢に出る対策 本当に効く攻撃 過去問での扱い
SQLで特別な意味を持つ文字を無効化(エスケープ) SQLインジェクション 正解として出題
プレースホルダ(静的プレースホルダ) SQLインジェクション 正解として出題
HTMLタグとして解釈されないよう処理 XSS XSSの問題では正解。SQLインジェクションの問題では誤答
「../」を受け付けない・ファイル名を外部から直接指定させない ディレクトリトラバーサル 他の攻撃の問題の誤答として登場
入力の長さ・大きさを制限する バッファオーバフロー 誤答として登場
ログアウト時にサーバ側でセッションIDを無効化・重要操作前の再認証 セッションハイジャック 正解として出題
利用者ごとに固定のセッションID (逆効果) 誤答として登場
Webアプリからシェルを起動できないようにする OSコマンドインジェクション 過去問では「セッションハイジャック対策」と入れ替えた誤答として登場
セッションIDに推測困難な乱数を使う セッションハイジャック(正しい対策) 過去問では「OSコマンドインジェクション対策」として並べた誤答で登場。その組合せなら誤り

対策の文を読んだら、まず「どこで悪さを防いでいるか(DB・HTML・ファイル・セッション)」を考え、攻撃名と合っているか確かめます。

要点(試験直前に読む)

  • SQLインジェクションは、Webアプリの不備を突いて悪意のある命令文を入力し、DBのデータを不正取得・改ざんする攻撃。このレッスンでいちばんよく出る。
  • SQLインジェクション対策は「特別な意味を持つ文字として解釈させない(エスケープ)」「プレースホルダで組み立てる」。試験ではどちらも正解。
  • XSSは閲覧者のブラウザでスクリプトを実行させる攻撃。対策は、画面に出すときにHTMLの特殊文字をエスケープすること。掲示板に保存するのが格納型、リンクを踏ませるのが反射型。
  • ディレクトリトラバーサルは「../」などのパス名を使って非公開ファイルを閲覧する攻撃。
  • セッションハイジャック対策は、ログアウト時にサーバ側でセッションIDを無効化すること、重要情報の直前でパスワード再認証すること。
  • オープンリダイレクトは、正規サイトの自動転送機能を悪用して偽サイトへ誘導する攻撃。

ひっかけ

  • 「HTMLタグとして解釈されないようにする」はXSS対策。SQLインジェクション対策を問う問題では誤答になる。「データベース」「SQL」が出てくるかで見分ける。
  • 「別のWebサイトで訪問者が意図しない操作を行わせる」はCSRFの説明。「ブラウザでスクリプトを実行させる」とあるXSSと取り違えない。
  • 「入力の長さ制限」はバッファオーバフロー、「../を受け付けない」はディレクトリトラバーサル、「OSにパッチを当てる」は一般的な脆弱性対策。どれもSQLインジェクション・XSSの対策としては誤り。
  • 対策の入れ替えに注意する。「シェルを起動できないようにする」はOSコマンドインジェクション対策、「推測困難な乱数のセッションID」はセッションハイジャック対策。過去問では両者を入れ替えた誤答が出ている。
  • セッションハイジャックの問題で「通信の暗号化」「IDをcookieに格納」「固定のセッションID」が出たら誤答。正解はサーバ側でのID無効化か、パスワードでの再認証。

用語(15)

SQLインジェクション エスキューエルインジェクション
入力欄に悪意のある文字列を入れてSQL文の意味を書き換え、データベースを不正に操作する攻撃。
⚠ XSSと混同しやすい。被害の場所がデータベースならSQLインジェクション、利用者のブラウザならXSS。
SQL Structured Query Language
データベースにデータの取得や更新を命令するための言語。
エスケープ処理 えすけーぷしょり
特別な意味を持つ文字を、ただの文字として扱われる形に置き換える処理。
⚠ SQL向け(データベースを守る)とHTML向け(ブラウザを守る)がある。問題文がどちらを守っているかで攻撃名を決める。
プレースホルダ ぷれーすほるだ(バインド機構)
SQL文の形を先に決め、入力値を後から値としてはめ込むことで、入力が命令として解釈されないようにする仕組み。
⚠ SQLインジェクション専用の対策。XSSやディレクトリトラバーサルの対策として並んだら誤り。
クロスサイトスクリプティング Cross-Site Scripting(XSS)
脆弱なWebサイトを経由して、攻撃者のスクリプトを閲覧者のブラウザで実行させる攻撃。
⚠ CSRFは「別サイトで本人が意図しない操作をさせる」攻撃。XSSは「ブラウザでスクリプトを実行させる」攻撃。
反射型XSS はんしゃがたクロスサイトスクリプティング
罠のリンクをクリックさせてスクリプト入りのリクエストを送らせ、レスポンスに埋め込まれたスクリプトを実行させるXSS。
⚠ 格納型はスクリプトがサーバに保存される。リンクのクリックなら反射型、掲示板への書込みなら格納型。
格納型XSS かくのうがたクロスサイトスクリプティング(Stored XSS / Persistent XSS)
掲示板などに攻撃スクリプトを書き込んで保存させ、後から閲覧した利用者のブラウザで実行させるXSS。
⚠ 反射型との見分けは上と同じ。
CSRF Cross-Site Request Forgery(クロスサイトリクエストフォージェリ)
罠のページを見た利用者に、ログイン中の別のWebサイトで本人が意図しない操作をさせる攻撃。
⚠ XSSと名前が似ている。「意図しない操作を行わせる」とあればCSRF。
ディレクトリトラバーサル Directory Traversal
上位のディレクトリを指す「../」などをファイル名に混ぜ、非公開のファイルにアクセスする攻撃。
⚠ OSコマンドインジェクションはOSの命令を実行させる攻撃。ファイルを読むだけならディレクトリトラバーサル。
OSコマンドインジェクション オーエスコマンドインジェクション
Webアプリ経由でOSの命令(コマンド)を実行させ、ファイルの操作などを不正に行う攻撃。
⚠ 対策は「Webアプリからシェルを起動できないようにする」。セッションハイジャック対策として並んだら誤り。
セッションID セッションアイディー
ログイン中の利用者を見分けるために、サーバが発行してブラウザに持たせる識別用の値。
セッションハイジャック Session Hijacking
他人のセッションIDを不正に入手し、その利用者になりすましてアクセスする攻撃。
⚠ 対策は、ログアウト時にサーバ側でIDを無効化することと、重要操作の前の再認証。通信の暗号化やIDの格納場所の変更は不正解。
再認証 さいにんしょう
重要な情報の表示や操作の直前に、パスワードなどで本人確認をもう一度行うこと。
オープンリダイレクト Open Redirect
Webサイトの自動転送機能を悪用し、攻撃者が指定した偽サイトへ利用者を誘導する攻撃。
⚠ HTMLメールのフィッシングは偽URLを直接リンクに書く。正規サイトの転送機能を使えばオープンリダイレクト。
バッファオーバフロー Buffer Overflow
確保したメモリの範囲を超えてデータを書き込み、プログラムを異常終了させたり不正なコードを実行させたりする攻撃。
⚠ 対策の「入力の長さを制限する」は、SQLインジェクションやXSSの問題で誤答としてよく並ぶ。

このレッスンの過去問

このレッスンで稽古する