Skip to content

[SECURITY] APIキーのlocalStorage保存によるXSS攻撃リスク #2

Description

@stewroux

深刻度: HIGH

問題の概要

Gemini APIキーを localStorage に保存しています。localStorage は同一オリジン上で動作するすべてのJavaScriptコードからアクセス可能なため、XSS(クロスサイトスクリプティング)攻撃が発生した場合にAPIキーが盗まれるリスクがあります。

影響ファイル

  • app/page.tsx (line 67-68)
    localStorage.setItem('gemini_api_key', key);
    localStorage.setItem('gcp_project_id', projectId);
  • app/page.tsx (line 43-44) — 読み込み時
    setGeminiKey(localStorage.getItem('gemini_api_key') || '');
    setGcpProjectId(localStorage.getItem('gcp_project_id') || '');

追加の問題点

console.error でAPIエラーを出力しているため、本番環境でも機密情報がブラウザコンソールに漏洩する可能性があります。

  • services/geminiService.ts (line 78): console.error("Error calling Gemini API:", error);
  • services/geminiService.ts (line 92): console.error("Error generating image summary:", error);
  • app/page.tsx (line 88): console.error('Failed to generate filename:', err);

推奨修正方法

APIキー保存の改善

フロントエンドでAPIキーを保持することは本質的にリスクがありますが、やむを得ない場合の緩和策:

  1. セッションストレージの使用(タブを閉じると消える):

    sessionStorage.setItem('gemini_api_key', key); // localStorage より安全
  2. 根本解決: #1(APIルート化)と組み合わせ、クライアント側にAPIキーを一切保持しない設計に変更する。

console.error の抑制

// 本番環境ではエラーログを抑制
if (process.env.NODE_ENV === 'development') {
  console.error("Error calling Gemini API:", error);
}

または、適切なエラー監視サービス(Sentry等)を導入する。

関連Issue


このIssueは自動コードレビューエージェントにより 2026-05-09 に作成されました。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions