6.6. XSS対策¶
Caution
本バージョンの内容は既に古くなっています。最新のガイドラインはこちらからご参照ください。
目次
6.6.1. Overview¶
6.6.1.1. Stored, Reflected XSS Attacks¶
XSS攻撃は、大きく分けて二つのカテゴリに分けられる。
Stored XSS Attacks
Reflected XSS Attacks
Stored XSS Attacks、Reflected XSS Attacksともに、出力値をエスケープすることで防ぐことができる。
6.6.2. How to use¶
必要に応じて、3種類のエスケープを使い分けること。
エスケープの種類:
- Output Escaping
- JavaScript Escaping
- Event handler Escaping
6.6.2.1. Output Escaping¶
| エスケープ前 | エスケープ後 | 
|---|---|
| & | & | 
| < | < | 
| > | > | 
| " | " | 
| ' | ' | 
f:h()を使用することを必須とする。6.6.2.1.1. 出力値をエスケープしない脆弱性のある例¶
出力画面の実装
<!-- omitted -->
<tr>
    <td>Job</td>
    <td>${customerForm.job}</td>  <!-- (1) -->
</tr>
<!-- omitted -->
| 項番 | 説明 | 
|---|---|
| (1) | customerFormのフィールドである、jobをエスケープせず出力している。 | 
6.6.2.1.2. 出力値をf:h()関数でエスケープする例¶
出力画面の実装
<!-- omitted -->
<tr>
    <td>Job</td>
    <td>${f:h(customerForm.job)}</td>  <!-- (1) -->
</tr>
.<!-- omitted -->
| 項番 | 説明 | 
|---|---|
| (1) | EL式の f:h()を使用することにより、エスケープして出力している。 | 
出力結果
<!-- omitted -->
<tr>
    <td>Job</td>
    <td><script>alert("XSS Attack")</script></td>
</tr>
<!-- omitted -->
- Tip - java.util.Date継承クラスのフォーマット - java.util.Date継承クラスをフォーマットして表示する場合は、JSTLの - <fmt:formatDate>を用いることを推奨する。 以下に、設定例を示す。- <fmt:formatDate value="${form.date}" pattern="yyyyMMdd" /> - valueの値に前述した - f:h()を使用して値を設定すると、Stringになってしまい、- javax.el.ELExceptionがスローされるため、そのまま- ${form.date}を使用している。 しかし、yyyyMMddにフォーマットするため、XSSの心配はない。
- Tip - java.lang.Number継承クラス、またはjava.lang.Numberにパースできる文字列 - java.lang.Number継承クラスまたはjava.lang.Numberにパースできる文字列をフォーマットして表示する場合は、 - <fmt:formatNumber>を用いることを推奨する。 以下に、設定例を示す。- <fmt:formatNumber value="${f:h(form.price)}" pattern="###,###" /> - 上記は、Stringでも問題ないので、 - <fmt:formatNumber>タグを使わなくなった場合に- f:h()を付け忘れることを予防するため、- f:h()を明示的に使用している。
6.6.2.2. JavaScript Escaping¶
| エスケープ前 | エスケープ後 | 
|---|---|
| ' | \' | 
| " | \" | 
| \ | \\ | 
| / | \/ | 
| < | \x3c | 
| > | \x3e | 
| 0x0D(復帰) | \r | 
| 0x0A(改行) | \n | 
6.6.2.2.1. 出力値をエスケープしない脆弱性のある例¶
<html>
  <script  type="text/javascript">
      var aaa = '<script>${warnCode}<\/script>';
      document.write(aaa);
  </script>
<html>
| 属性名 | 値 | 
|---|---|
| warnCode | <script></script><script>alert('XSS Attack!');</script><\/script> | 
出力結果
<script type="text/javascript">
    var aaa = '<script><\/script><script>alert('XSS Attack!');<\/script><\/script>';
    document.write(aaa);
</script>
- Tip - 業務要件上必要でない限り、JavaScriptの要素をユーザからの入力値に依存して動的に生成する仕様は、 任意のスクリプトが埋め込まれてしまう可能性があるため、別の方式を検討する、または、極力避けるべきである。 
6.6.2.2.2. 出力値をf:js()関数でエスケープする例¶
f:js()の使用を推奨する。使用例を、下記に示す。
<script type="text/javascript">
  var message = '<script>${f:js(message)}<\/script>';  // (1)
  <!-- omitted -->
</script>
| 項番 | 説明 | 
|---|---|
| (1) | EL式の f:js()を使用することにより、エスケープして変数に設定している。 | 
出力結果
<script  type="text/javascript">
    var aaa = '<script>\x3c\/script\x3e\x3cscript\x3ealert(\'XSS Attack!\');\x3c\/script\x3e<\/script>';
    document.write(aaa);
</script>
6.6.2.3. Event handler Escaping¶
f:h()や、f:js()を使用するのではなく、f:hjs()を使用すること。${f:h(f:js())}と同義である。<input type="submit" onclick="callback('xxxx');">のようなイベントハンドラの値に"');alert("XSS Attack");// "を指定された場合、別のスクリプトを挿入できてしまうため、6.6.2.3.1. 出力値をエスケープしない脆弱性のある例¶
<input type="text" onmouseover="alert('output is ${warnCode}') . ">
| 属性名 | 値 | 
|---|---|
| warnCode | '); alert('XSS Attack!'); //上記の値が設定されてしまうことで、意図せず文字列リテラルが閉じられ、XSSの脆弱性が生じる。 | 
出力結果
<!-- omitted -->
<input type="text" onmouseover="alert('output is'); alert('XSS Attack!'); // .') ">
<!-- omitted -->
6.6.2.3.2. 出力値をf:hjs()関数でエスケープする例¶
使用例を、下記に示す。
<input type="text" onmouseover="alert('output is ${f:hjs(warnCode)}') . ">  // (1)
| 項番 | 説明 | 
|---|---|
| (1) | EL式の f:hjs()を使用することにより、エスケープして引数としている。 | 
出力結果
<!-- omitted -->
<input type="text" onmouseover="alert('output is \'); alert(\'XSS Attack!\');\" \/\/ .') ">
<!-- omitted -->





