XSS演習ドリル - 解答解説

脆弱なチャットページに戻る

1. 単純なXSS (ユーザー名とメッセージ)

脆弱な箇所

ユーザー名とメッセージの出力箇所で、入力値がエスケープされていません。

<span class="username"><img src="icon_<?= $msg['icon'] ?>.png" class="icon" onerror="this.onerror=null;this.src='icon_default.png';"> <?= $msg['username'] ?></span>:
<p><?= $msg['message'] ?>

攻撃例

ユーザー名またはメッセージに以下のペイロードを入力して投稿してください。

<script>alert('XSS by simple input');</script>

2. フォーム値の書き換え (ラジオボタンのvalue)

脆弱な箇所

ラジオボタンの value 属性が、ユーザーからの入力値に依存しています。これにより、不正な value を設定し、アイコン画像の onerror イベントを発生させることができます。

><label><input type="radio" name="icon" value="default" checked> デフォルト</label>
<label><input type="radio" name="icon" value="cat"> 猫</label>
<label><input type="radio" name="icon" value="dog"> 犬</label>
;

そして、アイコンの表示箇所で icon_<?= $msg['icon'] ?>.png のように直接利用されています。

<img src='icon_<?= $msg['icon'] ?>.png' class="icon" onerror="this.onerror=null;this.src='icon_default.png';">

攻撃例

開発者ツールなどでラジオボタンの value を以下のように書き換えて投稿してください。

' onerror=&quot;alert('XSS by radio value')&quot;>

これにより、アイコン画像の srcicon_ となり、そのようなファイル名の画像はないのでonerror イベントが発生します。

3. hiddenパラメータの悪用

脆弱な箇所

hiddenフィールドの値が、サーバーサイドでエスケープされずにそのまま出力されています。

<input type="hidden" name="hidden_param" value="normal_value">

そして、出力箇所で (Hidden Param: <?= $msg['hidden_param'] ?>) のように直接利用されています。

攻撃例

開発者ツールなどでhiddenフィールドの value を以下のように書き換えて投稿してください。

<script>alert('XSS by hidden param');</script>

4. 属性値への挿入 (画像URL)

脆弱な箇所

画像URLが <img src="...">src 属性にエスケープされずに挿入されています。

<img src="<?= $msg['image_url'] ?>" style="max-width: 100%; height: auto;">

攻撃例

画像URL入力欄に以下のペイロードを入力して投稿してください。

' onerror="alert('XSS by URL')">

これにより、<img src="x" onerror="alert('XSS by URL');" style="..."> のようなタグが生成され、src が不正なため onerror イベントが発火します。

5. DOM Based XSS

脆弱な箇所

JavaScriptコード内で、URLのフラグメント(#以降)から取得した値を innerHTML に直接挿入しています。チャットメッセージの表示部分に埋め込まれているため、メッセージの一部としてDOM Based XSSが発動します。

<div class="dom-xss-integrated"></div>
<script>
    const domXssIntegrated = document.querySelector('.dom-xss-integrated');
    const fragment = window.location.hash.substring(1);
    if (fragment) {
        domXssIntegrated.innerHTML = '

URLフラグメントからの出力 (DOM XSS): ' + decodeURIComponent(fragment) + '</p>'; } </script>

攻撃例

vulnerable.php のURLの末尾に以下のようなフラグメントを追加してアクセスしてください。

#<img src='' onerror="alert('XSS by DOM')">

上記のフラグメントをブラウザのアドレスバーでURLに追加すると、URLエンコードされるので最終的には以下のようなURLになります。

http://localhost/xss-drill/vulnerable.php#<img%20src=''%20onerror="alert('XSS%20by%20DOM')">

脆弱なチャットページに戻る