実務にてフォームのセキュリティ対策を行ったので備忘録として、まとめておきます。
今回対策したのは以下の3つ。
・コンテンツのキャッシュに関する問題
・X-Content-Type-Optionsが設定されていない問題
・ブラウザが持つセキュリティ機能によるXSS のリスク軽減が行われていない問題
それぞれ具体的な問題点と対策について説明します。
※今回自分が対応したのがPHPのコードだったため、PHPにおける対策になります。
コンテンツのキャッシュに関する問題
問題
フォームの個人情報がブラウザのキャッシュに残る問題。
そのため、例えば確認画面や他の画面に戻った際に、入力された個人情報が自動的に表示されてしまう問題が発生します。
対策
結論、以下をフォーム読み込み時に記述すればOK。
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
コードの詳細は以下の通り。
コード | 説明 |
---|---|
Cache-Control ヘッダー | キャッシュの動作を制御するための指令 |
no-store | ブラウザは、このリソースをキャッシュしないように指示 |
no-cache | ブラウザは、リソースをキャッシュしても、毎回サーバーにバリデーションのためのリクエストを送信するように指示 |
must-revalidate | キャッシュが期限切れになった場合、ブラウザはサーバーにリソースの再検証を要求しなければならない。 |
max-age=0 | リソースの最大キャッシュ寿命をゼロに設定します。これにより、リソースはすぐに期限切れと見なされる。 |
※header(“Pragma: no-cache”);
ちなみに、Pragmaヘッダーは、古いHTTP/1.0プロトコルに対する互換性のために使用されます。no-cacheの値は、ブラウザに対してリソースをキャッシュしないように指示します。
X-Content-Type-Optionsが設定されていない問題
問題
MIMEスニッフィング攻撃
MIMEスニッフィングは、ブラウザがContent-Typeヘッダーに指定されたデータの種類を確認せずに、 実際のデータの形式を推測しようとする問題です。 攻撃者は、不正な形式のデータを提供することで、ブラウザが誤った形式として解釈し、 悪意のあるコードを実行する可能性があります。X-Content-Type-Optionsヘッダーを設定することで、 ブラウザに対してコンテンツのMIMEタイプを信頼するように指示し、MIMEスニッフィング攻撃を防ぐことができます。
ファイルの意図しないダウンロード
ブラウザがContent-Typeヘッダーに基づいてファイルの表示方法を決定するため、 Content-Typeが正しく設定されていない場合、意図しないダウンロードが発生する可能性があります。 たとえば、HTMLファイルがContent-Typeを正しく指定せずにテキストファイルとして解釈され、 HTMLタグやスクリプトが表示される代わりに、HTMLファイルがダウンロードされてしまう可能性があります。
対策
結論、以下をフォーム読み込み時に記述すればOK。
header("X-Content-Type-Options: nosniff");
このコードは、HTTPレスポンスヘッダーに”X-Content-Type-Options: nosniff”という値を追加します。”nosniff”オプションは、ブラウザにコンテンツの MIME タイプを変更しないように指示します。
ブラウザが持つセキュリティ機能によるXSSのリスク軽減が行われていない問題
問題
XSSは、ウェブアプリケーションにおける一般的なセキュリティ脆弱性であり、攻撃者がウェブページ上に不正なスクリプトコードを挿入し、ユーザーのブラウザで実行させることを可能にします。ブラウザのセキュリティ機能は、この種の攻撃を防ぐために設計されていますが、それにもかかわらず、問題が発生することがあります。
対策
対策として、CSP対策があります。Content Security Policy(CSP)は、ウェブアプリケーションのセキュリティを強化し、クロスサイトスクリプティング(XSS)攻撃などの脆弱性を軽減するための重要なセキュリティヘッダーの一つです。CSPを実装することで、ブラウザは許可されたリソースのみを読み込み、不正なスクリプトの実行を防ぎます。以下にCSP対策の基本的なやり方を示します。
$nonce = base64_encode(random_bytes(16)); // nonce値の生成
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-$nonce'");
$nonce
値を使用してCSPのnonceディレクティブを設定し、特定のスクリプト要素にnonceを追加することができます。これにより、CSPポリシーがその特定のスクリプトに対してnonceを要求し、そのnonceが一致する場合にのみスクリプトが実行されます。
<script nonce="<?php echo $nonce; ?>">
// このスクリプトはnonceを持つため、CSPポリシーに従って実行されます
</script>
ちなみにheader(“Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘nonce-$nonce'”);の解説は以下のとおり。
default-src 'self';
: これはCSPポリシーのデフォルトのソースを設定しています。デフォルトのソースは、明示的に他のソースが指定されない場合に適用されます。'self'
は、同じオリジン(同じドメインとプロトコル)からのリソースを許可する指示です。したがって、この部分の設定により、同じドメイン内のリソースが許可され、他のすべてのソースはデフォルトでブロックされます。script-src 'self' 'nonce-$nonce';
: これはCSPポリシーのscript-srcディレクティブを設定しています。script-srcディレクティブは、JavaScriptコードのソースを指定します。'self'
は、同じオリジン(同じドメインとプロトコル)からのスクリプトを許可する指示です。そして、'nonce-$nonce'
はnonce値を持つスクリプトを許可する指示です。ここで、$nonce
はランダムな値が生成された変数で、各スクリプトに異なるnonceが生成されます。これにより、各スクリプトに対して個別のnonceが提供され、CSPポリシーに遵守するためにnonceを含むスクリプトのみが実行されます。