💡 Key Takeaways
- Understanding the Attack Surface: What You're Really Protecting
- Input Validation: Your First Line of Defense
- Authentication and Authorization: Knowing Who and What
- SQL Injection: The Vulnerability That Won't Die
マーカス・チェン、フォーチュン500のフィンテック企業のシニアセキュリティエンジニア。ウェブアプリケーションの強化に12年の経験を持ち、日々20億ドル以上の取引を処理しています。
💡 主なポイント
- 攻撃対象面の理解: あなたが本当に保護しているもの
- 入力検証: あなたの最初の防御線
- 認証と認可: 誰と何を知ること
- SQLインジェクション: 死なない脆弱性
3年前、私は金曜日の午後4:47にジュニア開発者がコードを本番環境にプッシュするのを見ました。午後6:15には、私たちのセキュリティオペレーションセンターがクリスマスツリーのように光り輝いていました。見た目には無邪気な検索機能のSQLインジェクション脆弱性が、34万件の顧客記録を公開してしまったのです。この侵害は修復、規制罰金、および失われたビジネスで420万ドルの費用を要しました。その開発者は?ウェブセキュリティについて知らないことを知らない、素晴らしいエンジニアでした。
この事件は私のセキュリティ教育のアプローチを変えました。私はほとんどの開発者が無謀であるわけではなく、知識の空白で運営していることに気づきました。コンピュータサイエンスプログラムは、運が良ければセキュリティに2週間を費やします。ブートキャンプでは、まったく省略されることが多いです。それでも私たちは、レンガを積むことを理解しているだけで要塞を築くことを期待されているのです。
私は過去10年間、ペネトレーションテストから200人以上の開発チームが使用するセキュリティフレームワークの構築まで、ウェブセキュリティの現場で働いてきました。私は攻撃が粗雑なスクリプトキッドの試みから、洗練された国家による攻撃に進化するのを見てきました。そして、基本的な原則—すべての開発者が内面化すべき基本—は、あなたが思っているほど変わっていないことを学びました。これらのコア原則をマスターすれば、私は毎日本番コードで見る脆弱性の90%を防ぐことができるでしょう。
攻撃対象面の理解: あなたが本当に保護しているもの
開発者に何を保護しているか尋ねると、通常「ユーザーデータ」または「データベース」と答えが返ってきます。間違ってはいませんが、不完全です。あなたの攻撃対象面は、アプリケーションが入力を受け取り、データを処理し、外部システムと相互作用するすべてのポイントです。それは、ログインフォームであり、内部使用のみのために書いたAPIエンドポイント、管理パネルのファイルアップロード機能、さらにはユーザーに表示するエラーメッセージでもあります。
具体的な例を私自身の経験からお話ししましょう。私たちはユーザーの一括更新のためにJSONペイロードを受け入れる内部APIエンドポイントを持っていました。それは「内部専用」で、VPNからのみアクセス可能で、認証は不要でした。しかし、誰かがリバースプロキシを誤設定し、そのエンドポイントがインターネットに約18時間公開されてしまったのです。その18時間の間に、自動スキャナーがすでにこれを見つけ、2,847種類の異なる攻撃ベクトルを試みました。
攻撃対象面には、package.json または requirements.txt に含まれるすべての依存関係が含まれます。2021年12月にLog4Shellの脆弱性が発生したとき、私は72時間連続でチームが影響を受けたシステムを特定して修正するのを手助けしました。脆弱性は私たちが書いたコードにあるのではなく、依存関係の依存関係の依存関係にあるロギングライブラリにありました。あなたの攻撃対象面は、典型的なNode.jsアプリケーションの場合、800以上のパッケージを含む全依存関係ツリーを通じて広がっています。
アプリケーションの信頼境界について考えてみてください。どこから信頼されないデータがあなたのシステムに入りますか?すべてのフォームフィールド、すべてのURLパラメータ、すべてのHTTPヘッダー、すべてのクッキー、すべてのAPIリクエストボディ。サーバーのメモリの外から来る場合、それは信頼されないものです。開発者がフォーム入力を慎重に検証しながらURLパラメータを完全に無視しているのを見たことがあります。また、POSTデータを消毒してもGETパラメータが完全にオープンのままになっていることもあります。攻撃者は、何が「検証されるべき」かというあなたの精神モデルには関心がなく、すべてを探ります。
あなたの攻撃対象面には、時間ベースの脆弱性も含まれます。あなたが生成するパスワードリセットトークンは?予測可能であったり、期限切れにならなかったりする場合、それは攻撃ベクトルです。セッションID、APIキー、一時ファイル名—攻撃者が十分な時間を持って推測またはブルートフォース可能なものはすべてです。かつて、パスワードリセットトークンが順次整数であったシステムを見つけました。攻撃者は自分のアカウントのリセットを要求し、トークン45231を見た後、トークン45230、45229、45228を試して他のユーザーのパスワードをリセットできるというものでした。
入力検証: あなたの最初の防御線
もし私がすべての開発者の額に1つの原則をタトゥーとして刻むことができるなら、それはこれです: ユーザー入力を決して信頼しないこと。あなたのモバイルアプリからの入力を信じてはいけません。「信頼された」パートナーのAPIからの入力も信じてはいけません。あなた自身のフロントエンドJavaScriptからの入力でさえも。それを信頼境界を越えるものはすべて、検証、消毒され、そうでないことが証明されるまで潜在的に悪意のあるものと扱わなければなりません。
最も危険な脆弱性は、ハッカーが見つけるものではなく、開発者が自分のコードに存在することに気づかないものです。
私は開発者が同じミスを繰り返すのを見ます: フロントエンドで入力を検証し、それが十分であると仮定します。現実はこうです—私はブラウザの開発者ツールまたは単純なcurlコマンドを使って、あなたのフロントエンドの検証を約15秒でバイパスできます。フロントエンドの検証はユーザーエクスペリエンスのためであり、セキュリティのためではありません。実際の検証はサーバーで、毎回、例外なしに行われます。
効果的な入力検証には、3つの要素があります: 型チェック、フォーマット検証、ビジネスロジック検証です。型チェックは、数値を期待するフィールドが実際に数値を受け取っていることを確認します。文字列を含むSQLインジェクションの試みではありません。フォーマット検証は、データが期待されるパターンに一致することを保証するためにホワイトリスト(ブラックリストではなく)を使用します。メールアドレスを期待している場合、適切なメールの正規表現に対して検証してください。米国の電話番号を期待している場合、フォーマットを明示的に検証してください。
ビジネスロジック検証は、ほとんどの開発者が考えるのをやめるところです。技術的に有効だからといって、それがアプリケーションの文脈で意味があるとは限りません。かつて、ショッピングカートが負の数量を許可しているコードをレビューしました。開発者は入力が整数であることを検証していましたが、それが正であるかどうかは確認していませんでした。攻撃者は「-100」のアイテムを「購入」し、請求されるのではなくクレジットを受け取ることができました。修正は簡単でしたが、その見落としは発見される前に会社に2万3,000ドルの損害を与えました。
私の実践的なアプローチはこれです: アプリケーションが受け入れるすべての入力に対して厳格なスキーマを定義します。Node.js用のJoi、Python用のPydantic、またはLaravelやDjangoのようなフレームワーク内蔵の検証ライブラリを使用してください。これらのライブラリを使用すると、正しい入力がどのようなものかを正確に宣言でき、デフォルトで他のすべてを拒否します。検証が失敗した場合は、ログに記録します。同じIPアドレスまたはユーザーアカウントからの繰り返しの検証失敗は、進行中の攻撃を示す可能性があります。
もう1つ重要なポイント: すべての層で検証します。データがAPIからバックグラウンドジョブを経てデータベースに流れる場合、各ステップで検証します。APIは入力を正しく検証しましたが、バックグラウンドジョブはデータがデータベースから来ているため安全だと仮定しました。データベースに直接書き込むことができる攻撃者(別の脆弱性を通じて)は、すべての検証をバイパスできます。
認証と認可: 誰と何を知ること
認証は「あなたは誰ですか?」という問いに答えます。認可は「あなたは何をすることが許可されていますか?」という問いに答えます。これら2つの概念を混同したり、適切に実装しなかったりすると、私が遭遇する最も悪用されやすい脆弱性が生じます。私は堅牢な認証を持つシステムを見たことがありますが、認可が後回しにされたために、認証されたユーザーは誰でも他のユーザーのデータにアクセスできました。
| 脆弱性の種類 | 攻撃ベクトル | 予防方法 | 深刻度 |
|---|---|---|---|
| SQLインジェクション | データベースクエリにおける未検証のユーザー入力 | パラメータ化クエリ、ORMフレームワーク、入力検証 | 重大 |
| クロスサイトスクリプティング(XSS) | ウェブページに挿入された悪意のあるスクリプト | 出力エンコーディング、コンテンツセキュリティポリシー、消毒ライブラリ | 高 |
| クロスサイトリクエストフォージェリ(CSRF) | 信頼されたユーザーからの未許可のコマンド | CSRFトークン、SameSiteクッキー、オリジン検証 | 中 |
| 認証バイパス | 弱いパスワード、セッションハイジャック、壊れたロジック | 多要素認証、安全なセッション管理、レート制限 | T
Written by the Txt1.ai Team Our editorial team specializes in writing, grammar, and language technology. We research, test, and write in-depth guides to help you work smarter with the right tools. Related Tools Related Articles REST API Design Best Practices — txt1.ai Clean Code: 10 Principles That Make You a Better Developer — txt1.ai Essential Developer Tools in 2026: The Modern Stack — txt1.aiPut this into practice Try Our Free Tools → |