見出し画像

【AI文芸】玲奈の一夜 - CORS


🔹1. 午前2時、緊急コール

真夜中、オフィスが静まり返る中、玲奈のスマホが震えた。
ディスプレイには赤い文字──“Critical Alert: Unauthorized access detected”

「またかよ…」

眠気で霞む目を無理やり開き、Slackを開く。
社内チャンネルがざわついている。
SREチームが脅えるように状況をやりとりしている。

「異常アクセスが止まらない」「海外IPだ」「アクセスログが数万行を突破」

玲奈はため息をつきながら身支度を整える。
「真夜中に呼び出されんの、もう何度目だっけ?」
そう思いながらも、彼女は急いでタクシーに飛び乗った。


🔹 2. オフィス到着、漂う不穏な空気

午前2時半。
普段から薄暗いオフィスだが、今日はさらに重い空気が漂っている。
SOC(セキュリティオペレーションセンター)のモニターには真っ赤なログが流れ続けていた。

玲奈:「状況は?」

SOCスタッフの長谷川が必死にキーボードを叩きながら答える。
長谷川:「アクセス元はロシア、中国、東欧…IPを変えながら大量リクエストしてます。AWSのWAFが阻止しきれず、APIに直撃してるみたいで…」

玲奈:「APIのどこ?」

長谷川:「/user-info と /account/balance 辺りですね。どうやら本番環境からユーザー情報を引っ張ろうとしているようで…」

玲奈は顔をしかめる。
「……最悪だな」


🔹 3. 田辺、現る

その時、汗だく で駆け込んできたのは開発チームの田辺。
Tシャツが汗でびっしょりだ。息が荒い。

田辺:「ちょ、ちょっとヤバいっすね…?」

玲奈は田辺を冷淡な目で見る。
「お前、本番APIのCORS、どう設定してた?」

田辺は口ごもった。
「え、えっと…確か CorsLayer::permissive() か、allow_origin(Any)…」

玲奈:「"allow_origin(Any)" ?」

そう呟いた瞬間、周囲のスタッフが息を飲んだ。
CORSの専門知識がなくても、「これヤバいやつだ」ってのが分かる。


🔹 4. 問題のコード、露呈

玲奈は急いでリポジトリを検索し、該当箇所のコードを開く。

use tower_http::cors::{CorsLayer, Any};

let cors = CorsLayer::new()
    .allow_origin(Any)  // ❌
    .allow_methods(Any)
    .allow_headers(Any);

玲奈:「…はぁ??」

その苛立ちをこめた吐息に、田辺がビクッとする。

「マジで、"どこからでもアクセスOK" にしてんの?これ本番用のサーバーだよな?

「だ、だってフロントエンドの開発中にCORSエラーが面倒で…」

「お前さあ…」

玲奈は机を殴るでもなく、静かに椅子に座り込んだ。むしろ、その沈黙が怖い。


🔹 5. インシデントのヤバさ

田辺は怖々と口を開く。
「で、でもこれ、すぐ直せば大丈夫ですよね?」

玲奈:「…甘いよ。もう既に海外IPから大量アクセスされてんだろ?どう考えてもデータが狙われてるんだよ。
ユーザー情報が抜かれてるかもしれない。

田辺は青ざめる。
「…え、えっと、どうしよう…」

「お前は黙ってろ。さっさとコード直して再デプロイしろ」

玲奈は早口でSOCチームに指示を飛ばす。

  1. AWS WAFで特定のIPを遮断

  2. NGINXのリバースプロキシでレートリミット設定

  3. SIEMでログを徹底分析

  4. PR出たらすぐに本番反映

田辺:「え、ちょっと、PRって今から…?」

玲奈は無言でスクリーンを指差す。
「30秒で作れ。
次に "Any" の文字列見つけたら、お前、デプロイ権限剥奪な」


🔹 6. 緊迫の修正作業

田辺は震える手でコードを修正する。

let cors = CorsLayer::new()
    .allow_origin("https://frontend.example.com".parse().unwrap())  // ✅ 特定のオリジンのみ
    .allow_methods([Method::GET, Method::POST])  // ✅ 必要なメソッドだけ
    .allow_headers(["Authorization", "Content-Type"])  // ✅ 必要なヘッダーだけ
    .allow_credentials(true)  // ✅ 認証情報を送れる
    .use_max_age(std::time::Duration::from_secs(86400));  // プリフライトリクエストキャッシュ

田辺の背後で玲奈が腕を組み、じっと見つめている。
「フロントエンドが "OPTIONS" でちょいちょい文句言うなら max_age() で押さえ込めるだろ。
"Any" は二度と使うな。


🔹 7. デプロイ、怒涛のコミット

午前3時。
修正がコミットされ、CIパイプラインが回り始める。
テストが通り、わずか10分後に本番サーバーへデプロイが完了。

SOCのスタッフはアクセスログを監視する。
多少はまだ攻撃リクエストが来ているが、CORSポリシーの適切化+WAF設定 で応答はブロックされる。

長谷川:「ログイン必須APIにはもうアクセスできていません。データ漏洩の兆候は…今のところなし!」

玲奈はようやく肩の力を抜く。
田辺は椅子にもたれかかり、安堵の息をついた。


🔹 8. 玲奈の一喝

「田辺。今回のことで分かったよな?」

田辺は小さく頷く。
「…CORSを適当に設定しちゃいけない、ですよね」

そうだ。お前の "めんどくさい" で、会社が潰れる可能性があったんだよ。

玲奈は田辺のディスプレイをじっと睨む。
次に同じミスをしたら、nano で IDE 設定ファイルごと書き換えさせるからな。

「ひいいいいっ!!」


🔹 9. 余波

午前4時過ぎ。
インシデントは一応の収束を見せたが、SOCは引き続き監視を続ける。
田辺は警戒心に怯えた顔のまま、ログを眺めている。

玲奈はスマホを眺め、再びため息をつく。
「…この時間に呼び出されるの、ほんと勘弁してほしいんだけど」

「CORSを舐めた開発者がいる限り、私の睡眠時間は増えないんだな」

そう呟き、玲奈はペットボトルのお茶を一気に飲み干した。
夜はまだ終わらない。


🎯 まとめ

  1. 深夜2時のインシデントは最悪: 攻撃者は夜間を狙う。

  2. CORS設定ミスは重大: 「許可してはいけないオリジン」を開放すれば、情報漏洩の危機。

  3. "Any" は地獄の入り口: 本番では特定オリジン指定+allow_credentials(true) の正しい設定が必須。

  4. セキュリティインシデントは即対応: 放置すれば会社の信用が消し飛ぶ。

  5. 玲奈の一喝: 二度と同じミスをするな。夜中の呼び出しはもうごめんだ。

いいなと思ったら応援しよう!