PHPのXSS対策を完全ガイド!初心者でもわかる安全なWebアプリの作り方
生徒
「PHPのセキュリティでXSS対策ってよく聞くんですけど、そもそもXSSって何なんですか?」
先生
「XSSは『クロスサイトスクリプティング』と呼ばれる攻撃で、悪意のあるスクリプトがWebページに入り込む危険な問題だよ。」
生徒
「スクリプトってJavaScriptみたいなものですか?実際どういう被害が起きるんです?」
先生
「そう。JavaScriptが勝手に実行されてしまい、ログイン中のユーザー情報を盗まれることもあるんだ。今日はPHPで安全にするためのXSS対策を詳しく学んでいこう!」
1. XSS(クロスサイトスクリプティング)とは?初心者向けにやさしく解説
XSS(クロスサイトスクリプティング)とは、攻撃者が悪意を持って作成したJavaScriptなどのスクリプトを、ユーザーが閲覧するWebページに勝手に混入させ、実行させてしまう問題です。 初心者の方でもイメージしやすくすると、まるで「手紙の空白に勝手に落書きされ、その落書きに触るとスマホが勝手に動き出す」というようなイメージです。
PHPを使ってWebアプリケーションを作る場合、このXSSはとても重大なセキュリティ問題になります。 特にフォーム入力、コメント欄、検索フォーム、ユーザー名表示など「ユーザーが入力した内容をそのまま表示する場面」はXSS攻撃の代表的な入口です。
XSS攻撃で実際に起こる危険として以下のようなものがあります:
- ユーザーのクッキー(ログイン情報)が盗まれる
- 勝手に偽フォームが表示され情報が抜き取られる
- サイトの画面が書き換えられる
- ユーザーが意図しない動作を実行させられる
PHPで安全なWebアプリを作るためには、このXSS対策を「必須の基本知識」として身につける必要があります。 ここからは、初心者でも確実に理解できるように、実例を交えながらPHPで行うXSS対策を一つずつ解説していきます。
2. PHPで最も重要なXSS対策:htmlspecialchars() の使い方
PHPでXSS対策といえば、まず最初に覚えるべきが htmlspecialchars() という関数です。
この関数は、HTMLの特別な意味を持つ記号を無害化して表示してくれる働きをします。
たとえば、悪意ある攻撃者が次のような文字を入力したとします:
<script>alert('攻撃!');</script>
これをそのまま画面に表示すると、ブラウザがJavaScriptとして実行してしまい、攻撃が成立します。
そこで htmlspecialchars() を使います:
<?php
$user_input = "<script>alert('攻撃!');</script>";
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
?>
こうすると、ブラウザが特別な記号を文字として表示するため、攻撃コードは無害になります。 PHPで安全なWebアプリを作る上で最も重要な基本対策です。
3. ENT_QUOTES と UTF-8 を必ず指定する理由
htmlspecialchars() を使う時、よく初心者がやってしまうミスが「第2引数と第3引数を省略してしまう」ことです。
正しくは次のように指定します:
htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
なぜこれが重要なのか、初心者向けに分かりやすく解説します。
● ENT_QUOTES を付ける理由
ENT_QUOTESは「シングルクォートとダブルクォートの両方をエスケープする」という設定です。 これがないと一部の攻撃を防げません。
● UTF-8 を指定する理由
文字コードを指定しないと、ブラウザによっては正しくエスケープが行われず、攻撃が成功してしまう場合があります。 PHPのWebアプリでは基本的にUTF-8を使用するため、必ず指定することが推奨されます。
4. 入力値を加工・検証する「入力バリデーション」も重要
XSS対策では表示前のエスケープだけでなく、入力の段階で値をチェックする「入力バリデーション」も重要です。 入力バリデーションとは、ユーザーが入力した内容が正しい形式か確認する作業です。
たとえば、メールアドレスならメール形式か、数字なら数字のみか、名前なら長すぎないか、などを確認します。 攻撃者は「本来入力されるはずのないデータ」を送り込み、そこから突破口を作ろうとするため、適切なバリデーションが安全性を高めます。
PHPでは filter_input() や filter_var() を使うと簡単に検証できます。
5. JavaScriptに値を渡すときのXSS対策
画面に値を表示するだけでなく、JavaScript側にPHPの値を渡すときにも注意が必要です。 PHPでエスケープしても、JSの中身として解釈されると危険です。
安全に値を渡す方法は JSON エンコードです:
<?php
echo json_encode($value);
?>
JSONとして正しい形式にして渡すことで、意図していないコードが混入するリスクを避けられます。
6. PHPのテンプレートでのXSS対策
最近のPHP開発では、Blade(Laravel)やTwig(Symfony)などテンプレートエンジンを使うことが一般的です。
これらのテンプレートエンジンは基本的に「自動エスケープ機能」が備わっています。 そのため安全性が高まり、初心者でもXSS対策を正しく実践できます。
7. XSS対策のポイント整理
PHPでWebアプリケーションを作る際には、XSS対策が最重要事項です。
ここまで解説した htmlspecialchars() を中心に、入力バリデーション、JSONエスケープ、テンプレートエンジンの活用を行うことで、攻撃を大幅に防ぐことができます。