クライアントサイドのJavaScriptに露出したAPIキー
ブラウザに送られるもの——インラインスクリプト、バンドルされたJS、source map——は誰でも読めます。フロントエンドのコードに埋め込まれたシークレットキー(OpenAI、Stripeのシークレット、AWS、データベースURL)は、実質的に公開されているのと同じです。
これは何か
ビルドツールは、コンパイル時に環境変数をインライン展開します。クライアントのコードでシークレットを参照すると、それはすべての訪問者がダウンロードするJavaScriptバンドルに含まれてしまいます。
重要な区別があります。publishable/anon キー(Stripeの pk_live、Firebaseのweb設定)は公開されることを前提に設計されていますが、シークレットキー(sk_live、service-role キー、プロバイダーのAPIキー)はそうではなく、決してブラウザに届いてはいけません。
なぜ重要か
漏洩したプロバイダーのキーは、誰にでもあなたのアカウントで利用量を積み上げさせ——LLMの請求、SMSの料金、クラウドの費用——あるいはそのキーが許可するデータにアクセスさせてしまいます。
攻撃者は大規模にJavaScriptバンドルをスクレイピングし、キーのパターンを探しています。コミットされたシークレットは、公開後たいてい数分以内に悪用されます。
直し方
サードパーティのAPIは、ブラウザからではなく、サーバーのルートやバックエンドから呼び出してください。ブラウザはあなたのエンドポイントと通信し、キーはエンドポイントが保持します。
// app/api/summarize/route.ts (server-only)
export async function POST(req: Request) {
const { text } = await req.json();
const r = await fetch("https://api.openai.com/v1/responses", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
body: JSON.stringify({ model: "gpt-4o-mini", input: text }),
});
return Response.json(await r.json());
}Next.jsでは、NEXT_PUBLIC_ のプレフィックスが付いた変数だけがブラウザに露出します。このプレフィックスの後ろにシークレットを置かないでください。公開しても安全な値にのみ使いましょう。
シークレットが一度ブラウザに配信されたら、失効させて再発行してください。次のビルドから削除しても、すでにスクレイピングされたコピーは無効になりません。
FAQ
Stripeの publishable キー(pk_live)はフロントエンドにあると問題ですか?
いいえ。publishable キーは公開される前提のものです。リスクはシークレットキー(sk_live)で、これはサーバーサイドにとどめる必要があります。
キーを難読化するだけではだめですか?
だめです。難読化は簡単に元に戻せます。唯一の対策は、シークレットをクライアントから完全に排除することです。
ブログ記事
偽のAIクローラーが.envファイルを狙っている。自分のアプリを確認する方法
認証情報を狙うスキャナーがAIクローラーの名前を借りて許可リストをすり抜け、ある1つのファイルを要求しています。それがあなたの.envです。自分のファイルにアクセスできてしまわないか確認する方法と、その塞ぎ方を解説します。
Railwayの侵害:ダウンタイムなしでアプリのシークレットをローテーションする方法
攻撃者がAIやプラットフォームのAPIキーを狙ったことを受け、Railwayは全ユーザーに環境変数のローテーションを呼びかけました。自分への影響を確認する方法、アプリを止めずにすべてを入れ替える方法、そして次の侵害の被害を小さくする方法をまとめます。
AIで作ったアプリをリリースする?公開前にこの7つを確認しよう
AIコーディングツールは「安全にリリースできる」ではなく「動く」ことを最適化します。これは、リリースしたばかりのアプリでまず確認する7つの問題と、それぞれの対策です。
関連する解説
露出した .env ファイル:攻撃者はどうやってシークレットを見つけるか
到達可能な .env が1つあるだけで、スタック全体を明け渡すことになりかねません。
Supabase の Row Level Security(RLS):テーブルを確実に保護する
anon key は公開されています。それとデータの間にあるのはRLSだけです。
Firebase Security Rules:データベースを開けっ放しにしない
Firebaseの設定は仕様上公開されています。データを誰が見られるかはルールで決まります。
本番のsource mapはソースコードを漏らす
配信された .map ファイルは、元のソースを明け渡します。