Treur は正しく理解しましたが、いくつかのことを明確にし、参照資料のソースを提供したいと思います。Treur が言ったように、ブラウザーによって送信されたすべてのヘッダーを含むユーザー入力データを決して信頼しないでください。
あなたが説明しているのは、典型的なクロスサイト リクエスト フォージェリ攻撃です。RFC2616 ( Hyper Text Transfer Protocol 1.1 ) によると、リファラー ヘッダーはオプションであり、ブラウザーによっていつでも省略される可能性があるため、リファラーヘッダーのチェックは CSRF 攻撃に対する有効な保護ではありません。SSL を使用している場合、リファラー ヘッダーは常にブラウザーによって省略されます。第二に、これはユーザー定義の値であるため、信頼すべきではありません。
CSRF 攻撃に対する推奨される保護は、同期されたトークン パターンを使用することです。これは、非表示フィールドとしてフォームに埋め込まれたシークレット トークンを作成する必要があることを意味します。フォームが投稿されたら、シークレット トークンが存在し、有効であることを確認します。セキュリティ トークンを作成する方法は複数あります。トークンを作成する 1 つの方法について説明します。
アプリケーションのアクションごとに、一意のアクション名を作成します。たとえば、「delete_user」、「add_user」、「save_user_profile」などです。あなたが記述したフォームに「foobar」というアクション名があるとしましょう。アクション名をユーザーのセッション ID およびシークレット値と連結します。
$stringValue = "foobar" . "secret value" . session_id();
セキュリティ トークンを作成するには、連結された文字列のハッシュを作成します。sha1 を使用してハッシュを作成できます。ブルート フォース攻撃のリスクを軽減するには、ハッシュでより大きなキー (sha 512 など) を使用します。
$secretToken = hash("sha5125", $stringValue);
このトークンをフォームの非表示フィールドに設定します。フォームが送信されたら、トークンを再作成し、フォームで送信されたものと一致することを確認します。このトークンは、1 つのユーザー セッションに対して有効です。リクエストごとにトークンが再生成されるわけではないため、攻撃者がトークンを再利用できる機会があると主張する人もいるかもしれません。ただし、適切なセッション管理戦略があれば、これはあまり問題になりません。
私が言ったように、適切なセッション管理が必要です。これは、セッションを長時間存続させてはならないことを意味します。特にセッション固定の脆弱性は、攻撃者がユーザー セッションを制御し、秘密トークンを「予測」できるため、CSRF 保護手段を無効にします。
以下に、一読することをお勧めするリンクをいくつか示します。