【PHP】XSSについて動作を交えて学んでみる【必須知識】

PHPの勉強中なのでXSS(クロスサイトスクリプティング)について見ていきます。不足している点などがあればご指摘ください。


XSSって何?

Wikipediaで意味を調べてみます。

この拡張された定義においてXSS攻撃とは、攻撃者の作成したスクリプトを脆弱性のある標的サイトのドメインの権限において閲覧者のブラウザで実行させる攻撃一般を指す[3]。斜体で書いた部分がXSS攻撃の重要な特徴であり、この特徴により標的サイトの権限がないと実行できないようブラウザが制限している(同一生成元ポリシー)はずの行動を、攻撃者に実行可能にしてしまう[5]。

クロスサイトスクリプティング

頭のいい人はこれで理解できたかと思います。私は理解できなかったので実際にサンプルを作って動かしつつ学んでいきました。


タグが読み込まれるってどういう状況?

XSSを簡単に言ってしまえば、タグなどをフォームで送信して受け取る際にタグをタグとして読み込ませないということです。

<style> * {display:none}</style>

上記の<style>タグでは全称セレクタでdislay:none;を指定しているので<style>タグを読み込んだ時点でページが真っ白になってしまいます。

XSSはタグを認識させるようにすることで読み込んだページに悪意あるプログラムを埋め込むことでページ閲覧者のCOOKIE情報を抜き取るなどの悪意ある攻撃のことです。(例:<script>タグなど)


XSS対策とは?

XSSにはこういったタグを、タグとしてではなく文字として認識させるようにする(エスケープ処理)をしておく必要があります。

サンプル作ったのでそれを使って見てみます。

2つのフォーム(イメージ)

htmlspecialchars関数とは簡単に言えばタグを読み込ませないように特殊文字を置き換えるためのものです。

PHP: htmlspecialchars - Manual
文字実体参照一覧

<を&lt;として読み込んだり、>を&gt;として読み込ませることでブラウザがタグとして読み込まなくなるという仕組みですね。

[送信側]

<form action="送信先" method="POST">
  <input type="text" name="sample">
  <input type="submit" value="送信">
</form>

htmlspecialchars未対応

[受信側]

<?php echo $_POST['sample'];?>

htmlspecialchars対応済

[受信側]

<?php echo htmlspecialchars($_POST['sample']);?>

$_POST[‘sample’]で送信された内容を受け取ります。

$_POST[‘sample’]を直接出力してしまうとエスケープ処理がなくタグとして認識されてしまうので、$_POST[‘sample’]自体をhtmlspecialcharsで囲んで特殊文字を置換します。

実際にサンプルをアニメーションで見てみます。


サンプルで挙動を見てみる

htmlspecialchars未対応

htmlspecialchars未対応(上のフォーム)から先ほどの<style>タグを送信します。

<style> * {display:none}</style>

htmlspecialchars対応済

htmlspecialchars対応済(下のフォーム)から同様に<style>タグを送信します。

<style> * {display:none}</style>

htmlspecialchars未対応の方はページが真っ白になってしまってます。<style>タグが読み込まれているのがわかります。

一方で対応済みの方は文字として『<style> * {display:none}</style>を受け取りました』と1行目に書かれています。特殊文字をエスケープ処理できている状態ですね。


まとめ

PHPには他にもSQLインジェクションなどまだまだセキュリティ対策が必要です。PHPやSQLでできることは増えますが、セキュリティについてはしっかりと対応しておきましょう。