utsuroi xss labs 知識ベース 01 / 02 — HTML と DOM
HTML & DOM Basics · Knowledge Base
01

HTML と DOM の基礎

Tags, attributes, and how the browser executes scripts

XSS(Cross-Site Scripting)を理解するには、まず「HTML とは何か」「ブラウザはどのタイミングで JavaScript を実行するか」を押さえる必要があります。XSS はこの実行タイミングを攻撃者が乗っ取る攻撃です。

1. HTML タグの構造 #html-tag

開きタグ・本文・閉じタグ。

HTML は要素(element)の入れ子で構成されます。各要素は通常、開きタグ・内容・閉じタグの形を取ります。

<p>これは段落です</p>
<h1>見出し</h1>
<a href="...">リンク</a>

一部の要素(<img><br> 等)は閉じタグを持たない「空要素」です。

2. 属性とは #html-attribute

タグに付加情報を持たせる仕組み。

要素には属性を付けて、追加情報を与えられます。属性は 名前="値" の形式で、開きタグ内に書きます。

<a href="https://example.com" target="_blank">クリック</a>
<img src="photo.jpg" alt="写真">
<input type="text" name="email" value="user@example.com">

属性値は通常ダブルクォート(または シングルクォート)で囲みます。値の中に同じクォートを含めたい場合はエスケープが必要。

3. DOM(Document Object Model) #dom

HTML をプログラムから操作できるツリー構造。

ブラウザは HTML を読むと、それをメモリ上で木構造として保持します。これが DOM。JavaScript はこの木構造に対して、要素の追加・削除・属性の変更などができます。

document         (ルート)
└── html
    ├── head
    │   └── title
    └── body
        ├── h1
        ├── p
        └── div

JavaScript からは document.getElementById('foo')document.querySelector('.bar') 等で要素にアクセスできます。

4. script タグと JavaScript の実行 #script-tag

ブラウザは <script> を見つけたら、その中身を「コード」として実行する。

HTML の中に <script>...</script> があると、ブラウザはその中身を JavaScript コードとして実行します。

<script>
  alert('こんにちは');
</script>

外部ファイルから読み込むこともできます:

<script src="app.js"></script>
これが XSS の核

もし攻撃者が「ページの HTML に <script> タグを差し込む」ことができれば、その中身がブラウザで実行されてしまいます。XSS の最も基本的なベクトルは、HTML 出力の中に <script> タグを注入することです。

5. イベントハンドラ属性 #event-handler

<script> 以外でも JavaScript は実行できる。

HTML の要素には onclickonerroronmouseover 等のイベントハンドラ属性があり、属性値として書かれた JavaScript が、特定のイベントが発生したときに実行されます。

<button onclick="alert('クリックされました')">押してね</button>
<img src="存在しない.jpg" onerror="alert('読み込み失敗')">

特に <img onerror=...> は重要。意図的に存在しない画像を指定すれば onerror が必ず発火するので、攻撃者は <script> がフィルタされている場面で <img src=x onerror="..."> を使います。

よくある攻撃ベクトル

<img src=x onerror="alert(1)"> はブラウザに「x という画像を読みに行け、失敗したら onerror を実行せよ」と指示。x は存在しないので必ず失敗 → 必ず onerror が実行されます。

6. innerHTML — DOM への HTML 挿入 #innerhtml

JavaScript で「文字列を HTML として」挿入する API。

JavaScript には、文字列を HTML として要素の中に挿入する API があります。代表的なのが innerHTML

document.getElementById('greeting').innerHTML = '<b>こんにちは</b>';

'<b>こんにちは</b>' という文字列が HTML としてパースされ、太字のテキストになります。

危険な使い方

innerHTML にユーザ入力を直接渡すと、その入力が HTML として解釈されます。これは Reflected XSS や DOM-based XSS の典型的な原因です。

// 危険
element.innerHTML = userInput;

// 安全(テキストとして扱う)
element.textContent = userInput;