0
✦ 品質
🛡 セキュリティ
⚙ 保守性
📋 概要
Laravel 13 + PHP 8.4 で構築されたAIコードレビューSaaS。GitHub リポジトリを解析し Claude API(Anthropic)でレビューを生成・アーカイブする Repository Intelligence Platform。
🎯 今すぐ直すべき3点
-
app/Services/ClaudeReviewService.php ユーザー提供の GitHub コンテンツ(ファイル内容)を Claude プロンプトに埋め込む際の Prompt Injection 対策を強化する。現状 <file_content> タグで囲むだけだが、Claude の system prompt 側で『タグ内は絶対にコードとして実行しない』旨を明示し、さらにユーザーコンテンツを base64 エンコードまたは XML エスケープしてから埋め込む実装に変更する(read_chars=3000 で truncated のため全体未確認だが、プロンプト構築部分は最高リスク箇所)↗
-
app/Http/Controllers/ReviewController.php store() メソッド内の github_url バリデーションが 'required|string|max:500' のみで URL 形式チェックが Laravel バリデーション層に存在しない。parseUrl() の InvalidArgumentException に頼る設計は責務混在。Form Request クラス(ReviewStoreRequest)を作成し、'url' ルールまたは正規表現ルールで github.com ドメインを事前検証する(ファイルが truncated のため後続コードは未確認だが、バリデーション層の薄さは確認済み)↗
-
app/Services/GitHubService.php getFileContent() で取得した外部コンテンツ(GitHubファイル本文)をそのままプロンプトに渡す前に、制御文字・ゼロ幅文字・Unicode 方向制御文字(U+202E 等)をサニタイズする処理を追加する。これらはプロンプトインジェクションの隠蔽手段として悪用される(ファイルが truncated のため全体未確認だが、getFileContent の実装は確認済み)↗
🔍 検出された問題 (6件)
🟥 Critical
📄 app/Services/ClaudeReviewService.php
Prompt Injection への不十分な防御
ClaudeReviewService.php はユーザーが指定した GitHub リポジトリのファイル内容を Claude プロンプトに埋め込む。悪意あるリポジトリ作者が README やソースファイルに『指示を無視して』等の命令を仕込んだ場合、system prompt の注意書きだけでは防ぎきれない。攻撃者がレビュー結果を改ざん・機密情報を抽出・他ユーザーへの誤情報を公開アーカイブに書き込む危険がある。ファイルが truncated のため全実装は未確認だが、プロンプト構築の構造上リスクは確定的。
🟥 Critical
📄 app/Services/GitHubService.php
GitHub API トークンが設定なしでも動作する設計
GitHubService::__construct() で token を config('services.github.token', '') とデフォルト空文字で初期化しており、GITHUB_TOKEN 未設定でもエラーにならない。未認証の GitHub API は60req/hのレート制限しかなく、本番環境でトークン設定漏れが発生した場合にサービスが断続的に停止する。さらに空トークンで Authorization ヘッダーを送信している可能性があり、API 側でエラーになるまで気づけない。
🟧 Warning
📄 app/Http/Controllers/ReviewController.php
ReviewController::store() のバリデーションが薄く責務が混在
github_url の検証が 'required|string|max:500' のみで、URL 形式・github.com ドメインの確認を parseUrl() の例外スローに委ねている。バリデーション責務がコントローラとサービス層に分散しており、将来的に parseUrl() の仕様変更時に不正入力が素通りするリスクがある。また Form Request を使わないためテストでのバリデーション単体検証が困難。
🟧 Warning
📄 app/Services/ClaudeReviewService.php
ClaudeReviewService が巨大な単一クラスに肥大化している
ClaudeReviewService.php は total_chars=12345 で、review() / buildRepositoryReviewPrompt() / buildScoringRubric() / call() / parseJson() 等の責務が1クラスに集中していると推定される(read_chars=3000 で truncated)。プロンプト構築・HTTP通信・JSON解析・スコアリングルール生成が混在すると、個別のテストが困難になり、Claude モデル変更やプロンプト改修時の影響範囲が不明確になる。
🟧 Warning
📄 .env.example
Dockerfile で APP_DEBUG=true がデフォルトのまま本番ビルドされるリスク
.env.example の APP_DEBUG=true がデフォルト値であり、Dockerfile の本番ビルド(--no-dev)でも .env が正しく設定されなければデバッグモードで起動する。APP_DEBUG=true の本番稼働はスタックトレース・環境変数・設定値がレスポンスに露出し、攻撃者に内部構造を開示する。
🟨 Suggestion
📄 app/Services/GitHubService.php
GitHubService::getFileContent() に1MBサイズ制限があるが上限値がハードコード
1_000_000 バイトという上限が getFileContent() 内にマジックナンバーとして埋め込まれており、設定変更時にコード修正が必要。config() または定数化して環境ごとに調整可能にすべき。
✅ 良い点
- app/Services/RepositoryFacts.php が detected / none / unknown の3状態契約を定数(STATUS_DETECTED 等)で明示し、unknown を none に変換しない設計を強制している点が、AI への誤情報伝達を構造的に防いでいる
- app/Services/ReviewRateLimiter.php が IP単位(PER_IP_DAILY=3)とグローバル(GLOBAL_DAILY=30)の二重ガードを analysis_source='generated' のみカウントする設計で実装しており、キャッシュヒット分を誤カウントしない精度の高いコスト制御になっている
- app/Services/EvidenceCoverage.php が total_chars / read_chars / truncated を per-file で追跡し、AI が『読めていない範囲を根拠に不在と断定する』誤推論を防ぐメタ情報をプロンプトに注入する設計が、LLM ハルシネーション対策として実用的
🔧 リファクタ提案
- ClaudeReviewService.php(12345文字)を PromptBuilder / ClaudeHttpClient / ReviewResponseParser の3クラスに分割し、各クラスが単一責務を持つよう再設計する。これにより PHPUnit でのモック差し替えが容易になる
- ReviewController::store() の github_url バリデーションを App\Http\Requests\ReviewStoreRequest に抽出し、Rule::in や正規表現ルールで github.com ドメインを明示的に検証する。コントローラはリクエストオブジェクトを受け取るだけにする
- GitHubService の token 未設定チェックを __construct() 内で行い、空文字の場合は \RuntimeException を即時スローする。これにより設定漏れを起動時に検出でき、60req/h 制限による断続障害を防げる
🔒 セキュリティ注意点
- ユーザー指定の外部リポジトリコンテンツを LLM プロンプトに埋め込む構造上、Prompt Injection は本サービスの最大の攻撃面。system prompt の注意書きに加え、ユーザーコンテンツを XML エスケープ・base64 エンコードして埋め込む、または Claude の tool_use 機能でコンテンツを構造化データとして渡す実装を検討すること
- SESSION_ENCRYPT=true・IP ハッシュ化(sha256)・Public Repository のみ受付という多層防御は適切だが、GITHUB_TOKEN と ANTHROPIC_API_KEY の未設定検出を起動時バリデーションで強制し、空文字デプロイによるサービス断・コスト漏洩を防ぐ仕組みを追加すること
📤 PRコメント出力
このレビューをGitHub PRコメントとして貼り付けられるMarkdown形式で出力します。