情報処理安全確保支援士過去問題 令和5年秋期 午後 問1
⇄問題PDFと解説を画面2分割で開く⇱問題PDF設問1
解答入力欄
解答例・解答の要点
- イ
- レビュータイトルを出力する前にエスケープ処理を施す。
解説
- 掲示板のように動的にHTMLを組み立てるWebサイトの脆弱性を悪用して、攻撃者が用意した悪意のあるスクリプトを埋め込む攻撃がXSS(クロスサイトスクリプティング)です。XSSは、その特徴によりDOMベース、格納型、反射型に分類されます。
【DOM Based XSS】
Webブラウザ側で動的にHTMLコンテンツを変更するWebページで発生しうる攻撃です。
攻撃者は、悪意のあるスクリプトを含むURLパラメータ(?以降の部分)やフラグメント識別子(#以降の部分)を仕込み、そのリンクをユーザーにクリックさせます。Webページがそれらの値を利用して組み立てたHTMLでDOMの変更操作を行うことにより、Webページ上にそのスクリプトが挿入され、実行されます。
DOMはDocument Object Modelの略で、HTMLやXMLで記述された各要素をアプリケーションプログラムから取り扱うための仕組みです。// 攻撃者の用意したURL【格納型XSS(蓄積型XSS・持続型XSS)】
https://example.com/page.html#<script>alert('DOM XSS');</script>
// 被害を受けるサイト上のJavaScriptコード
hash = location.hash.substring(1);
document.getElementById('output').innerHTML = hash;
掲示板やクチコミサイトなどユーザー生成コンテンツを扱うWebページで発生しうる攻撃です。
攻撃者が悪意のあるスクリプトを入力フォームから送信し、そのスクリプトがサーバ側のファイルやデータベースに保存されます。WebサーバがそのデータをもとにHTMLを組み立てて出力することで、Webページを閲覧した人のWebブラウザ上でスクリプトを実行されます。不正なスクリプトが埋め込まれたページを表示しただけで発動するので、不正なスクリプトが取り除かれない限り永続的に動作します。// 攻撃者が入力フォームから送信され、サーバに保存される文字列【反射型XSS(非持続型XSS)】
<script>alert('Stored XSS');</script>
// サーバが出力するHTML
<div class="review">
<p>Great product!</p>
<script>alert('Stored XSS');</script>
</div>
Webサーバがユーザーからのリクエストに基づいてHTMLを動的に生成し、出力として返すWebページで発生しうる攻撃です。
攻撃者は、悪意のあるスクリプトを含むURLパラメータを仕込み、そのリンクをユーザーにクリックさせます。WebサーバがそのデータをもとにHTMLを組み立てて出力することで、Webページを閲覧した人のWebブラウザ上でスクリプトを実行されます。格納型と異なりスクリプトは保存されないので、リンクをクリックした人に対する一度きりの攻撃となります。// 攻撃者の用意したURL本問では「NさんがページVを閲覧してみると,画面遷移上おかしな点はなく,図2(ページV)が表示された」とあります。特定のURLへのアクセスを条件とするわけではなく、会員とNさんに対して同じ不正なスクリプトが埋め込まれたページが表示されています。このため、閲覧しただけで発動する「格納型XSS」と判断できます。
https://example.com/search?q=<script>alert('Reflected XSS');</script>
// サーバが出力するHTML
<p>Search results for: <script>alert('Reflected XSS');</script></p>
∴イ:格納型XSS - XSS脆弱性に対する根本的な対策は、Webページの本文やHTMLタグの属性値など、すべての出力要素にエスケープ処理を施すことです。XSS対策としてのエスケープ処理(サニタイジング)では、ユーザーから受け取った入力値をHTMLとして出力するときに、少なくとも & < > ' " の5種類の文字を実体参照※1(& < > ' ")に置き換える必要があります。この5つの文字は、HTMLの構造や属性値を定義するために用いられます。これらの文字を適切にエスケープすることで、攻撃者がHTMLコードを意図的に操作し、スクリプトを埋め込むことを防止できます。
図3を見ると、下から5行目において会員Bの投稿中の文字列「>_<」が>_<に変換されているため、レビュー詳細の欄についてはエスケープ処理がされていることがわかります。しかし、図3の6行目で<script>がそのまま出力されているなど、レビュータイトルの欄はエスケープ処理がされていません。攻撃者はこの脆弱性を突いてXSSを仕掛けています。したがって、今回のXSS攻撃を防ぐためにWebアプリQが実施すべき対策は、レビュータイトルを出力する際にエスケープ処理を行うこととなります。
∴レビュータイトルを出力する前にエスケープ処理を施す。
※1 HTMLエンティティとも呼ばれます。
設問2
解答入力欄
解答例・解答の要点
- HTMLがコメントアウトされ一つのスクリプトになるような投稿を複数回に分けて行った。
解説
今回の攻撃はレビュータイトルの欄のXSS脆弱性を突いたものでしたが、図1の5.によると、レビュータイトルの欄には50字の入力文字数制限があります※2。しかし、図4の文字数全体は明らかに50文字を超えています。単純にレビュータイトルを複数回に分けて投稿しても、途中にスクリプトとは無関係のタグが挿入されるため、意味のある一連のスクリプトにはなりません。そのため、図4のような複雑なスクリプトを埋め込むためには、何らかの細工が必要になります。
図3のレビュータイトルに出力された文字列をよく見ると、投稿内容の末尾に/*、先頭に*/があります。これは、JavaScriptにおいて複数行のコメントアウトを記述するための記号です。/*と*/で囲まれた部分はコメント部として扱われ、表示に関与しなくなります。これにより、レビュータイトルとレビュータイトルの間のHTMLが無効化され、一連のスクリプトとして認識されます。攻撃者はこの方法により、複数回に分けて長文のスクリプトを挿入していたと判断できます。
図3の出力内容の一部がスクリプト内部でコメントアウトされる様子は次のとおりです。
図3のレビュータイトルに出力された文字列をよく見ると、投稿内容の末尾に/*、先頭に*/があります。これは、JavaScriptにおいて複数行のコメントアウトを記述するための記号です。/*と*/で囲まれた部分はコメント部として扱われ、表示に関与しなくなります。これにより、レビュータイトルとレビュータイトルの間のHTMLが無効化され、一連のスクリプトとして認識されます。攻撃者はこの方法により、複数回に分けて長文のスクリプトを挿入していたと判断できます。
図3の出力内容の一部がスクリプト内部でコメントアウトされる様子は次のとおりです。
<div class="review-title">Good
<script>xhr=new XMLHttpRequest();
/* コメントアウト
</div>
・・・
<div class="review-title">
*/
url1 = "https://□□□.co.jp/user/profile";
/* コメントアウト
</div>
・・・
<div class="review-title">
*/
xhr2.send(form);</script></div>
∴HTMLがコメントアウトされ一つのスクリプトになるような投稿を複数回に分けて行った。<script>xhr=new XMLHttpRequest();
/* コメントアウト
</div>
・・・
<div class="review-title">
*/
url1 = "https://□□□.co.jp/user/profile";
/* コメントアウト
</div>
・・・
<div class="review-title">
*/
xhr2.send(form);</script></div>
設問3
解答入力欄
解答例・解答の要点
- XHRのレスポンスから取得したトークンとともに,アイコン画像としてセッションIDをアップロードする。
- 会員のアイコン画像をダウンロードして,そこからセッションIDの文字列を取り出す。
- ページVにアクセスした会員になりすまして,WebアプリQの機能を使う。
解説
- 6~20行目のスクリプトの動作を確認します。
- 6行目 - XMLHttpRequest(以下、XHR)の結果受取り時に実行するコールバック関数の定義です。末尾の{から20行目の}までが一連の処理として動作します。
- 7行目 - XHRのレスポンスを変数 page に代入します。
- 8行目 - 変数 page からCSRFトークンの値を取り出し、変数 token に代入します。
- 9行目 - 新しいXHRオブジェクトである変数 xhr2 を定義します。
- 10行目 - 画像のアップロード先URLを変数 url2 に代入します。
- 11行目 - POSTメソッドと url2 でXHRオブジェクトを初期化します。
- 12行目 - 入力フォームを定義します。
- 13行目 - 利用者のcookie情報を変数 cookie に代入します。
- 14行目・15行目 - ファイル名をa.pngに、ファイルタイプをimage/pngに設定します。
- 16行目 - 中身が変数 cookie で、PNG形式の画像に偽造したファイルオブジェクトを新規作成します。
- 17行目 - formにキーがuploadfile、値が変数 file のオブジェクトを格納します。
- 18行目 - formにキーがtoken、値が変数 token のオブジェクトを格納します。
- 19行目 - xhr2をサーバに送信します。
∴XHRのレスポンスから取得したトークンとともに,アイコン画像としてセッションIDをアップロードする。
問題文中には「WebアプリQがHttpOnly属性を付与していないこと及びアップロードされた画像ファイルの形式をチェックしていないことも確認した」とあります。HttpOnly属性が付与されていれば、JavaScirptからcookie情報にアクセスできなくなり、攻撃を防げたと考えられます。同様に、画像ファイルの形式をチェックしていれば、画像ファイルに偽装されたテキストファイルのアップロードを拒否できたでしょう。 - 攻撃者が悪意あるスクリプトを仕掛けた状態で、正規の利用者がページVにアクセスすると、そのスクリプトが自動的に実行されます。スクリプトは利用者のクッキー情報(セッションID)を取得し、その情報を画像ファイルとしてサーバにアップロードします。このアップロードが成功すると、クッキー情報を含むファイルがその会員のアイコン画像として登録されることになります。
その後、この偽の画像ファイルは商品レビューページのアイコン画像として表示されます。攻撃者は商品レビューページにアクセスし、この画像ファイル(実体はテキストファイル)をダウンロードすることで、画像の中身をテキスト形式で確認し、セッションIDを抽出することができます。図2の画面例でいえば、会員Bのアイコン画像をダウンロードすることで、会員BのセッションIDを取得可能です。
∴会員のアイコン画像をダウンロードして、そこからセッションIDの文字列を取り出す。 - セッションIDは、Webアプリケーションがログイン後の利用者を特定するための識別子であり、Webアプリ側ではcookieによりログインの有無や利用者の識別を行っています。このため、攻撃者が不正取得したセッションIDを自分のWebブラウザのcookieに設定し、その状態でWebアプリQにアクセスすれば、正規の会員になりすましてWebアプリQにアクセスすることができます。攻撃者は、正規の会員として、商品購入などの行動やアカウント情報の取得・変更などを行うことができます。
∴ページVにアクセスした会員になりすまして、WebアプリQの機能を使う。
設問4
解答入力欄
解答例・解答の要点
- スクリプトから別ドメインのURLに対してcookieが送られない仕組み
解説
図4のスクリプトが攻撃者のサイトに配置され、それが実行された場合、アクセス中のドメインとは別のドメインに対してリクエストが行われることになります。しかし、Webブラウザにはスクリプトから異なるドメインへのリクエストを制限する「同一オリジンポリシー」の仕組みがあります。
同一オリジンポリシーでは、異なるドメイン(オリジン)から取得したリソースについて、スクリプトからのアクセスを制限します。また、スクリプトから異なるドメインにリクエストを送信する際、原則としてcookieを送信しません※3。このため、会員がログイン状態(cookie情報にセッションIDを含む状態)で攻撃者のサイトにアクセスし、WebアプリQにXHRリクエストを送信(図4の5行目)しても、会員のセッションIDは送信されません。このリクエストはセッションエラーとなるため、トークンを取得することができず、攻撃は成立しません。
本問ではWebブラウザの仕組みが問われているため、同一オリジンポリシーに基づくWebブラウザの動作を解答します。したがって、「スクリプトから別のドメインに対してcookieが送られない仕組み」が適切となります。
∴スクリプトから別ドメインのURLに対してcookieが送られない仕組み
※3 クロスドメインでcookieを送信する仕組みとしてCORS(Cross-Origin Resource Sharing)があります。次のように設定します。
同一オリジンポリシーでは、異なるドメイン(オリジン)から取得したリソースについて、スクリプトからのアクセスを制限します。また、スクリプトから異なるドメインにリクエストを送信する際、原則としてcookieを送信しません※3。このため、会員がログイン状態(cookie情報にセッションIDを含む状態)で攻撃者のサイトにアクセスし、WebアプリQにXHRリクエストを送信(図4の5行目)しても、会員のセッションIDは送信されません。このリクエストはセッションエラーとなるため、トークンを取得することができず、攻撃は成立しません。
本問ではWebブラウザの仕組みが問われているため、同一オリジンポリシーに基づくWebブラウザの動作を解答します。したがって、「スクリプトから別のドメインに対してcookieが送られない仕組み」が適切となります。
∴スクリプトから別ドメインのURLに対してcookieが送られない仕組み
※3 クロスドメインでcookieを送信する仕組みとしてCORS(Cross-Origin Resource Sharing)があります。次のように設定します。
- クライアント側では、XMLHttpRequestのwithCredentialsをtrueに設定する
- サーバ側では、レスポンスにAccess-Control-Allow-OriginとAccess-Control-Allow-Credentialsの2つのヘッダーを付与して返す