仕組みから学ぶ Web

認証 / セキュリティ

誰であるかを証明し、なりすましを防ぐ

認証は「セッションをサーバーが覚える」か「トークンに書いて持たせる」かの選択から始まる。この選択が、ログアウトの実装可能性・スケール特性・漏洩時の被害範囲をすべて決める。攻撃手法は、その選択の穴を突いてくる。

読み終わると、これに答えられるようになります

  • ?JWT を使うとなぜ即時ログアウトが難しくなるのか
  • ?SameSite=Lax だけで CSRF は防げるのか
  • ?アクセストークンを localStorage に置くと何が起きるのか
基礎14分

Cookie とセッション — 状態を持たない HTTP に記憶を持たせる

サーバーが覚えるか、利用者に持たせるか。この選択が、ログアウトの実装可能性とスケール特性をすべて決める。

Secure 属性を付け忘れたセッション Cookie が、社内 Wi-Fi の平文通信で盗まれた

応用14分

JWT — 取り消せない代わりに、問い合わせが要らない

署名付きトークンが解いた問題と、その代償。「ステートレスだからスケールする」の裏で何を諦めているのか。

退会したユーザーが、24時間有効な JWT でその後もAPIを叩き続けられた

発展16分

OAuth 2.0 と OIDC — 「代理で使わせる」と「誰かを証明する」は別物

認可と認証を混同すると穴が開く。認可コードフローがなぜ遠回りに見える手順を踏むのか、一歩ずつ理由がある。

アクセストークンでログイン判定を実装し、他サービスのトークンで別人になりすまされた

応用16分

XSS・CSRF・SQLi — データとコードの境界が壊れる

3つの代表的な脆弱性は、どれも「データとして扱うべきものが命令として解釈される」という同じ形をしている。

検索キーワードをそのまま画面に出す実装で、管理者のセッションが盗まれた

応用14分

認可 — ログインしている人が、そのデータを触ってよいとは限らない

URL の注文番号を1つ変えるだけで、他人の注文と住所が見えた。ログインを確かめることと、そのデータを触ってよいかを確かめることは、別の仕事。

URL の注文番号を1つ変えるだけで、他人の注文と住所が見えた。3週間で8万件が取得されていた

応用14分

パスワードの保存 — 漏れたあとに、何日持ちこたえられるか

「パスワードはハッシュ化していたので安全」と発表した数日後、大半が元に戻され、他のサービスで不正ログインが続いた。速いハッシュは、漏れた瞬間から総当たりの的になる。

「ハッシュ化していたので安全」と発表した数日後、流出したパスワードの大半が元に戻された

応用15分

依存パッケージ — 自分が書いていないコードが、本番で動く

直接入れたのは40個。実際に入っていたのは900個。そのうち1つのメンテナのアカウントが乗っ取られ、CI の資格情報が外部へ送られた。

小さなユーティリティのパッチ版が乗っ取られ、CI のデプロイ用の資格情報が外部へ送られた

応用15分

監査ログ — 「誰がやったか」を、あとから言えるか

顧客データが 3 万件持ち出された。管理画面のログはあった。しかし誰がどのデータを見たかは、どこにも残っていなかった。

顧客データの持ち出しが疑われたが、誰が何を見たかを示す記録がどこにも無かった

応用15分

セキュリティヘッダ — 最後の1枚を、ブラウザに張らせる

XSS は塞いだつもりだった。広告タグの1つが改ざんされ、そこから入力欄の値が外部へ送られた。自前のコードは1行も侵されていない。

外部の広告タグが改ざんされ、決済フォームの入力値が第三者へ送信された

応用16分

プロンプトインジェクション — 読ませた文章が、命令に変わる

LLM には、データと命令を分ける仕組みがない。SQL のプレースホルダにあたるものが存在しない以上、守りは「騙されない」ではなく「騙されても被害が出ない」側に置くしかない。

社内 AI アシスタントに Web ページを要約させたら、社内文書の中身が外部へ送られた

発展16分

AI エージェントの権限 — 道具を持たせた瞬間に、認可の問題になる

エージェントは、誰かの権限を借りて動く。その権限が仕事に対して広すぎると、読ませた文章 1 つで、持ち主が意図しない操作が正規の権限のまま実行される。

Issue を直させたコーディングエージェントが、非公開リポジトリの中身を公開の場所に書き込んだ

応用14分

AI に送ったデータの行方 — 預け先より、手元のログのほうが長く残る

提供元が学習に使わないことは確かめた。けれどプロンプトは、送る前に自分のアプリのログ・監視・エラー通知を通っている。削除の依頼が来たとき、消せないのはそちらだった。

LLM の提供元は学習に使わない契約だったが、プロンプト全文が自社のログに 2 年残っていた