あかね
フロントのバリデーションは防御じゃない
2026年05月04日
見出しはありません
要約を生成中...
バリデーションはフォームの実装で行いますが、現場で知ったサーバー側でバリデーションしないと何が起きるのかについて書いてみます。
「フロントでバリデーションしてるから大丈夫やろ?」
これは普通に破られます。というかそもそも前提が間違っています。。。!
ブラウザってただのクライアントの一つなんですよね。
Postmanでもcurlでもスクリプト(Railsのrakeとか)でも、アプリを経由せずに直接APIを叩けます。
開発者以外でもです。当然できます。
たとえばこれ。
POST /api/orders
{
"price": -1000
}フロントでは1以上とかで弾かれるはずのリクエストですけど、普通に送れます。
フロントのバリデーションって、ブラウザを通ってる前提でしか機能しないんですよね。
最初この観点持ってなくてびっくり仰天でした。POSTMAN使ってAPIの動作確認のための登録とかしてたのに都合いいデータしか来ない前提で考えてた自分にもだいぶびっくりw
ここがこの話の核心です。
フロントのバリデーションって、ユーザーを迷わせないためのものなんですよ。
「この項目必須ですよ」「数字で入れてください」みたいな、UXの話です。
サーバーのバリデーションは全然違います。不正なリクエストを通さないための防御です。
役割がまるで違うので、フロントで担保しようとするのがそもそもズレてます。
最終的にデータの不整合を起こさないように、データを守れるのはサーバー側だけです!!!
クライアントは実際誰かわからんし、信じてはだめ!!!!!
堅牢なシステムって、一箇所だけで守ろうとしないんですよね。
層 | 役割 |
|---|---|
フロント | ユーザーの入力ミスを防ぐ(UX的観点) |
サーバー | 不正なリクエストを弾く(業務ロジックの入り口) |
DB | データの整合性を守る(最終的な防波堤) |
全部必要で、どれか一つで済む話じゃないです。
{ "price": -1000 }これが通ると、マイナス価格になって決済ロジックが崩れて売上計算がおかしくなることは容易に想像できます。バグの話じゃなくてビジネスの話になってきます。
{ "userId": "他人のID" }これ「不正な値を送ってる」問題に見えるんですけど、本質はそもそもuserIdをリクエストで受け取る設計がおかしいです。
// ❌ これはダメ
const { userId } = req.body;
// ⭕ こうする
const userId = session.user.id;誰が操作するかはサーバーが決めることで、クライアントに決めさせちゃいけません。(リクエスト飛ばしてきた人と実際のログインユーザーが一致しているか確認するのが認証認可ですね)
想定外のデータが入ると、画面が落ちたりバッチがコケたり集計がズレたりします。
しかも不整合なデータができてバグった状態で後から直すのがめちゃくちゃ大変になると思います。
それだとリクエストはもうサーバーに届いてます。
エラーの制御もできないし、権限チェックや業務ルールはDBじゃ防げないです。
DBはあくまで最後の変なデータを登録させないための保険であって、防御の主役じゃないです。
その前段で守っておくべきです。
ちょっと視点を変えると、サーバーのバリデーションって単なるエラーチェックじゃないんですよね。
APIって「こういう入力が来る前提で動く」という約束の上に成り立ってます。
この形式で送られてくる
この値の範囲である
このユーザーが操作する
などなど、この前提が崩れると、ロジックは正しく動きません。
だからバリデーションって想定外を弾くんじゃなくて、前提を保証するものなんです。
この考え方を持つと、どこで何をチェックすべきかが自然と見えてきます。
じゃあフロントのバリデーションってなんのため?ですよね😅
UXのためです。
「このユーザーが操作する」という項目は、『認可』と呼ばれる分野ですが、広い意味ではこれもAPIとの大事な契約の一部です。形式が合っていても、適切な権限がないリクエストは、システムにとっては『不正なデータ』でしかないです。
信じられないですよね、私もびっくりしました。でも出会ったんです。
AIでサーバーとフロント両方のコードを生成
忙しさが異常でそのままセルフマージしたみたい
サーバー側はレイヤードアーキテクチャでAPIの入り口で正しくformオブジェクトでバリデーションはちゃんとされてました。
問題はフロント側で、バリデーションエラーのメッセージも何も出ないでリクエストは飛ぶので422が返ってきても何が要件を満たしていないのかユーザーで理解できるエラーメッセージが何も表示されない状態になってました。
登録しようとするとエラー出てること以外わかんない。
ユーザー(開発してるのに私が冗談抜きでわかんなかった。APIの実装とかテーブル構造見たらわかるけどそういう問題ではない。開発してるエンジニアでこれ。)からしたら「どこ直せば保存できる??」としかならない。
AIが生成したコードって一見ちゃんとしてるように見えるんで、こういうの本当に気づきにくいんですよね。
これなんで保存できないかわかんない状態になってるって問題提起したら、DB設計が読めない人みたいな扱いされて心外だったw
アプリケーション経由でしかリクエストが飛んでこないと思い込んではいけないと感じた内容です。
そしてAIのとほほ、、、な感じの現場のエピソードも交えつつの内容でした!
私たちはどこで何を守るべきか常に考えなければならないですね。セキュリティ的にもですが、データを正しく保存するという当たり前のこともです。
コメント
まだコメントはありません。