入力バリデーション
サーバーサイドバリデーション・ホワイトリスト方式・型強制による不正入力からの防御の実装方針
入力バリデーションは、外部から入力されるすべてのデータを信頼しないというゼロトラストの原則に基づき、アプリケーションが期待する形式・範囲・型に合致するかを検証するプロセスである。クライアントサイドバリデーションはUX向上のために有効だが、JavaScriptを無効化するかHTTPクライアントで直接APIを呼ぶことで容易に迂回できるため、セキュリティ上の保護としては役立たない。サーバーサイドバリデーションは常に必須であり、クライアントサイドとの二重実装が前提となる。
ホワイトリスト(許可リスト)方式は、許可する値・形式を明示的に定義し、それ以外をすべて拒否するアプローチであり、ブラックリスト(拒否リスト)方式と比較して見落としが少なく堅牢である。例えば、メールアドレスのバリデーションにおいて特定の危険な文字を除外するブラックリスト方式よりも、RFC準拠のメール形式パターンに合致するかを確認するホワイトリスト方式の方が安全である。Zod(TypeScript)・Joi(JavaScript)・class-validator(NestJS)などのバリデーションライブラリを使うことで、スキーマ定義から型安全なバリデーションを一元管理できる。
型強制(Type Coercion)の罠とは、動的型付け言語において意図しない暗黙の型変換によってバリデーションをバイパスできる問題である。JavaScriptでは"0" == falseがtrueになるなど、==による比較が予期しない結果を生む。厳密等価演算子(===)の使用と、バリデーション前に明示的な型変換を行うことで回避できる。大量データ入力によるDoS攻撃には、JSONペイロードサイズの上限設定・配列長制限・ネスト深さ制限などを組み合わせて対処する。
コードレビューで着目するポイント
- すべての外部入力(クエリパラメータ・リクエストボディ・ヘッダー等)にサーバーサイドバリデーションが実装されているか
- ホワイトリスト方式が採用されており、特定のフォーマットへの合致確認が行われているか
- バリデーションライブラリ(Zod・Joi・class-validator等)が一貫して使われているか
- 数値パラメータに上限・下限の範囲チェックが設定されているか
- リクエストボディのサイズ上限が設定されているか(サーバーフレームワークのデフォルト値確認)
- ファイルアップロード時に拡張子・MIMEタイプ・ファイルサイズの検証が行われているか
- 配列・文字列の最大長チェックが実装されており、DoS攻撃耐性があるか
典型的なアンチパターン
クライアントサイドのみのバリデーション: フォームの必須チェックをJavaScriptで実装しているが、APIにはバリデーションがない。Curlで直接リクエストすると空のフィールドでもデータが保存され、DBの制約エラーが直接クライアントに返ってスキーマ情報が漏洩する。
ブラックリストによるSQLインジェクション対策: '(シングルクォート)など特定の文字を除外することでSQLインジェクションを防ごうとする実装。Unicodeエスケープや文字エンコーディングの違いにより迂回されることがある。プリペアドステートメントによるパラメータ化が唯一の確実な対策。
暗黙の型変換への依存: if (userId == "admin") のような==比較により、userIdが意図しない型の値でも条件が成立してしまうケース。厳密等価演算子===を使い、受け取る型を事前に明示的にキャストして確認すること。
参考リソース
- Zod (https://zod.dev/) — TypeScript向けスキーマ定義・バリデーションライブラリ
- OWASP Input Validation Cheat Sheet — 入力バリデーション実装の包括的なガイド
- Joi (https://joi.dev/) — JavaScript向けオブジェクトスキーマバリデーションライブラリ
- express-validator (https://express-validator.github.io/) — ExpressJSのリクエストバリデーションミドルウェア
- OWASP Testing Guide: Testing for Input Validation — バリデーションバイパスの試験手法
- 1. 📄アーキテクチャスタイル
- 2. 📄ドメインモデリング
- 3. 📄モジュール分割と依存管理
- 4. 📄データモデリング
- 5. 📄API設計
- 6. 📄整合性とトランザクション
- 7. 📄非同期処理(Queue/Event)
- 8. 📄キャッシング
- 9. 📄ユーザーリサーチ
- 10. 📄情報アーキテクチャ
- 11. 📄インタラクションデザイン
- 12. 📄UX原則とヒューリスティクス
- 13. 📄アクセシビリティ(UX観点)
- 14. 📄UXメトリクス
- 15. 📄スケーラビリティ
- 16. 📄可用性とレジリエンス
- 17. 📄オブザーバビリティ
- 18. 📄環境・インフラ設計
- 19. 📄データマイグレーション
- 20. 📄セキュリティ設計原則
- 21. 📄データ保護とマルチテナント
- 22. 📄LLMセキュリティ
- 23. 📄ビジュアルデザイン原則
- 24. 📄デザインシステム
- 25. 📄コンポーネント設計
- 26. 📄スタイリング
- 27. 📄設計原則
- 28. 📄デザインパターン(GoF)
- 29. 📄エンタープライズパターン
- 30. 📄クリーンコード
- 31. 📄リファクタリング
- 32. 📄型設計とコントラクト
- 33. 📄関数型プログラミング概念
- 34. 📄エラーハンドリング
- 35. 📄テスト戦略と哲学
- 36. 📄テスト種別(機能テスト)
- 37. 📄テスト種別(UI・ビジュアル)
- 38. 📄テスト種別(契約・境界)
- 39. 📄並行処理・マルチスレッド
- 40. 📄パフォーマンス最適化
- 41. 📄ドキュメント管理
- 42. 📄バージョン管理と開発プロセス
- 43. 📄脅威モデリング
- 44. 📄通信保護(TLS)
- 45. 📄暗号化・機密情報管理
- 46. 📄認証・セッション管理
- 47. 📄認可・アクセス制御
- 48. 📄入力バリデーション
- 49. 📄インジェクション攻撃
- 50. 📄正規化(データベース正規化)