なぜPOSTなのか?CSRFバリデーション実装から見えてきたHTTPメソッドのリアル
はじめに
こんにちは、工藤(https://x.com/tatsuya_restart)です。
「フォームの送信、POST か GET か問題」
これ、入門書には必ず載っていますが、実務では“仕様書に書いてあるから”では済まされない選択です。
PHP で社内向けの業務システムを実装していたとき、CSRF 対策を要件に含むフォーム実装を任されたことがありました。
このとき初めて、「POST にする理由」をHTTP の仕様レベル・攻撃モデル・セキュリティ要件の観点から逆算して考える必要が出てきたのです。
そもそも GET って何がダメなのか?
GET は「リソースの取得」専用です。つまり “結果に副作用がない前提” で使うべきもの。
一方、フォームの多くは「状態を変更する」用途(DB への登録、ファイル更新など)が中心。
GET でこうした操作を許すと、次のような脆弱性につながるケースがあります:
- GET リンクを踏むだけでデータが消える(id を URL に付けた場合)
- 検索ボットが誤って更新を実行
- キャッシュや履歴に敏感データが残る
POST は CSRF 対策との親和性が高い
私が実務で直面したのは、CSRF(クロスサイトリクエストフォージェリ)対策が要件に入ったとき。
この対策を PHP で実装しようとすると、トークンによるバリデーションを行います。
if ($_POST['token'] !== $_SESSION['token']) {
exit('不正なリクエストです');
}
ここで重要なのは、
- トークンはセッションに保存し、
- フォームの <input type="hidden" name="token" value="..."> に埋め込み
- サーバーで POST リクエストと照合する
というフローです。
GET メソッドでも理論上できないことはないですが、GET は URL でトークンが露出するため、リファラーやログで漏れる可能性があり、実務ではまず避けます。
補足: POST でも油断は禁物
ちなみに POST を使っても、トークンの生成や検証が不十分だと、CSRF を防げません。
- セッションごとにトークンを発行し、
- フォーム表示時と送信時でトークンを照合、
- 成功・失敗に関係なくトークンを再発行
といったワンタイムトークン戦略まで意識して初めて、POST の利点が活かせます。

結論:POST はセキュリティの前提条件
PHP などのバックエンド開発では、「この機能は GET でいい?POST にすべき?」という判断を日々行います。
単に「POST なら URL に出ないから安全」ではなく、攻撃モデル(CSRF, XSS)と HTTP 仕様に基づいた判断ができるようになると、ワンランク上の設計ができると実感しました。
おわりに
POST と GET の使い分け、入門ではさらっと触れられがちですが、実務ではフォームとセキュリティの設計そのものです。
「なぜ POST なのか?」を深掘りすることは、結果的に堅牢なアプリケーション設計へとつながります。
YouTube では動画で Udemy 並に解説してます
- Laravel
- React
- TypeScript
- Javascript
など現場で使える技術を公開してます!
Discussion