認証・認可でログインまわりを守れても、Webアプリには開発中に気をつける穴がいくつもあります。その入口をまとめます。
概要 — まず全体をつかむ
詳細 — 1段階ずつ追う
根っこの考え方
すべての土台は「外から来たものは信用しない」。ブラウザから届く値も、URLのパラメータも、疑ってかかる。これを忘れると、次のような穴になります。
この部分をもっと深く(中級)
多くのWeb脆弱性は「信頼できない入力が、ある境界を越えて悪さをする」構図です。だから対策も境界ごとに決まります。
- ブラウザへ出す境界 → 出力エスケープ(XSS対策)
- DBへ渡す境界 → パラメータ化(SQLインジェクション対策)
- 他サイトからの操作の境界 → トークン/SameSite(CSRF対策)
- コードと秘密の境界 → シークレット管理(秘密情報の隔離)
登場人物メモ:
- ※1 信頼境界 — 信用できる領域と、できない領域の境目
- ※2 多層防御 — 対策を重ね、1つ破られても次で止める
アニメーション『信頼境界(外は信用しない)』を開く
守りの主なポイント
- 入力の検証 — 外から来た値を、そのまま使わず確かめる(型・範囲・形式)
- XSS対策 — 出力を安全にして、他人のブラウザで悪いスクリプトを動かされないように
- CSRF対策 — ログイン中を悪用した「勝手な操作」を防ぐ
- SQLインジェクション対策 — 入力を通じてDBに不正な命令を送らせない
- 秘密情報の管理 — 鍵・パスワードをコードに直書きせず、隔離する
攻撃は、アプリと外の世界が触れ合う「境界」で起きます。だから守りも、境界ごとに置きます。
アニメーション『攻撃は境界で起きる』を開く
それぞれの詳しい手口と防ぎ方は、この下の各テーマで扱います。
この部分をもっと深く(中級)
- 入力検証 — 型・範囲・許可リストで、想定外を弾く(土台)
- XSS — 出力を文脈に応じてエスケープ、CSP でスクリプト実行を制限。なぜ効くか=出力文脈(HTML属性・JS・URL)ごとに変換規則が違い、文脈に合った変換で初めて無害化されるため
- CSRF — CSRFトークン+SameSite Cookie。SameSite は「クロスサイトからの Cookie 自動送信を抑制」することで、他サイト起点のなりすまし操作を成立させにくくする
- SQLインジェクション — プレースホルダ(パラメータ化クエリ)。なぜ効くか=命令(SQL文)とデータ(入力値)を分離し、入力を文字列連結でSQLに混ぜないため
- 秘密管理 — 環境変数・シークレットマネージャ、鍵のローテーション
- その他 — アクセス制御(認可)、依存ライブラリの更新、監査ログ
大事な姿勢
- 多層で守る — 1つの対策に頼らず、入力検証・出力エスケープ・権限確認を重ねる
- サーバで最終確認 — フロントのチェックは親切機能。本当の守りはサーバ側
- 既定は安全側 — 迷ったら「拒否・非公開」から始める
この部分をもっと深く(中級)
- 既定は拒否 — 許可リスト方式(deny by default)
- 依存の管理 — 使っているライブラリの既知の脆弱性を放置しない
- 運用・監視 — 攻撃に気づける状態を保つ(運用の全体像は Webのセキュリティ(全体像))
- 代表的な指標 — OWASP Top 10 のような整理を出発点にする
⚠️ 定番の事故
- 入力をそのまま画面に出す → XSS
- 入力をそのままDB命令に混ぜる → SQLインジェクション
- 鍵をリポジトリに置く → 秘密情報の漏洩
- 公開設定のミス → 見えてはいけないデータの露出
この部分をもっと深く(中級)
- 境界の取り違え — フロントで検証したから安全、と誤解(サーバで必ず再検証)
- 単一対策依存 — WAFだけ・エスケープだけに頼る
- 設定・依存の放置 — 公開設定ミス、古いライブラリの穴
理解度チェック
そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。
問1. Web開発の守りで、いちばん根っこにある考え方は?
問2. 秘密の鍵やパスワードの扱いとして正しいのは?
問3. 入力をそのまま画面(HTML)に出してしまうと起きる定番の事故はどれ?
問4. 鍵やパスワードをソースコードのリポジトリに置いてしまうと、何が起きる?
問5. フロント(ブラウザ側)のチェックの位置づけとして正しいのは?
問6. 作りかたに迷ったときの「既定(デフォルト)」として安全なのは?
問7. 入力をそのままDBの命令に混ぜて不正な操作をさせる攻撃を、何インジェクションと呼ぶ?
問8. 1つの対策に頼らず、入力検証・出力エスケープ・権限確認などを重ねて守る考え方を「◯◯防御」と呼ぶ。◯◯は?