PHPで特に覚えておきたいことを4つに絞ってざっくり!まとめてみました。
XSS クロスサイトスクリプティング
フォームの投稿でJavaScriptを埋め込むなど悪意のある攻撃を受ける場合があります。
それらの攻撃を対策する必要があります。
その対策をXSS(クロスサイトスクリプティング)と呼びます。
例えば、POST形式で受け取った値を下記のようにします。
htmlspecialchars($_POST['message'], ENT_QUOTES);
とし、htmlspecialchars()関数で囲むことでタグを無効化します。
こちらは何度も使うので下記のように関数化するのが便利です。
function h($str){ return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); }
あとは対策としてフォームのサニタイズもきちんと書いていきましょう
二重投稿防止
セキュリティ面を踏まえてきちんとした記述をしていないと、フォームで投稿後にリロードすることで
二重投稿ができてしまう、なんてことがあります。
これを防ぐために、二重投稿防止の記述をする必要があります。1つのファイル内ですべて済ますのではなく、結果を表示するファイルと、データを処理するファイルで分けます。
formのアクション属性を自分自身(例えばindex.phpならindex.phpとする)action="index.php"としましょう。
POST処理もif文で
if($_SERVER[’RWQUEST_METHOD’] === 'POST'){ //POST処理 header('Location: ◯◯◯◯/thanks.php'); exit; }
とし、index.phpに書き込みます。
あとは結果の表示するページへリダイレクトします。ここでは結果表示ページをthanks.phpとします。
フォームの脆弱性 CSRF
フォームなどの実装で悪意のある投稿をされる場合があります。
例えば、予期せぬページへ飛ばすようなリンク先とかですね。
これをCSRF(シーエスアールエフ クロスサイト リクエストフォージェリー)と呼びます。
CSRF対策としましては
フォームを生成するときにinput type="hidden"などで推測が難しいトークンを作ってあげます。
トークンがSessionにセットされていなかったらSessionのトークンを作ります。
if(!isset($_SESSION['token'])){ $_SESSION['token'] = bin2hex(random_bbytes(32)); }
binx2hexは16進数の文字列にする関数です。
あとはフォームに以下のような形で埋め込みます。
<input type="hidden" name="token" value="<?= h($_SESSION['token']);">
プリペアードステートメント
フォームで入力した値を受け取る場合にSQLによる攻撃を受けることがあります。
例えば、取得条件をいじられて1つ削除したいものを全削除にしたりとかですね。
「SQLインジェクション」と呼びます。
この攻撃を防ぐ方法として「プリペアードステートメント」を活用します。
prepare() メソッドを使ってプレースホルダを埋め込めるようにします。
$stmt = $pdo->prepare("DELETE FROM testPost WHERE likes < ? ");
最後はexecute() メソッドで閉じます。
$stmt->execute($n);
値を埋め込むSQLの場合は、安全に値を受け取るために「プリペアードステートメント」を必ず活用するようにしましょう。