crafted by Mize ↗
Open Repository Intelligence Open Repository Intelligence
CodeLens ACTIVE
CodeLens Engine
StatusOnline
Versionv0.4
ModelClaude Sonnet
Latency—
0
GOOD
改善余地があります
mize1978/codelens-ai
AIでコードのセキュリティ問題を指摘するツールが、自分自身のプロンプトインジェクション対策とDockerシークレット管理という最も基本的な問題を抱えているという、完璧なメタ皮肉を体現している
⭐ 1 Stars
·
🍴 0 Forks
·
📝 69 Commits
·
💬 0 Issues
·
🔵 Blade
·
Laravel
🔍 重要ファイル 12 件を精査 全 152 ファイル中 AI が優先度順に選択
0
✦ 品質
0
🛡 セキュリティ
0
⚙ 保守性
📋 概要

Laravel 13 + Claude AI を使ったGitHubリポジトリ自動コードレビューツール。GitHubのファイルツリーを取得してClaude Sonnetに送信し、品質スコア・Issue・修正提案をJSON形式で返すWebアプリ。

🎯 今すぐ直すべき3点
  1. app/Services/ClaudeReviewService.php buildReviewPromptメソッド内で $owner/$repo をプロンプトに直接展開している(ファイル末尾で切れているが構造上明らか)。GitHubから取得したリポジトリ名にプロンプトインジェクション文字列が含まれる場合に攻撃が成立するため、sanitizeInputをowner/repo にも適用し、<user_input>タグで囲んでサニタイズ済みであることを明示すること
    ↗
  2. Dockerfile Stage 2でCOPY . . を実行後に composer install しているが、.env.example が存在する場合 .env も混入リスクがある。.dockerignore に .env を必ず追加し、シークレットがイメージレイヤーに焼き込まれないことを確認すること。また php:8.4-alpine のタグをダイジェスト固定(例: php:8.4-alpine@sha256:...)にしてサプライチェーン攻撃を防ぐこと
    ↗
  3. app/Http/Controllers/ReviewController.php fixメソッドのRateLimiterキーが 'fix:' + IP hashのみで、Reviewモデルのオーナーシップ検証が存在しない。他人のReview IDを指定してfix APIを叩けるため、review->owner/repo を使ってGitHub APIを呼び出す処理が任意ユーザーにより乱用可能。fixメソッドにip_hashとreviewのip_hashを比較するポリシーまたはGateチェックを追加すること
    ↗
🔍 検出された問題 (7件)
🟥 Critical 📄 app/Services/ClaudeReviewService.php
ClaudeReviewServiceのプロンプトにowner/repoが無害化なしで展開される可能性
buildReviewPromptメソッド(ファイル末尾で切断)でGitHub URLから取得した $owner/$repo を直接プロンプト文字列に埋め込んでいる。悪意あるリポジトリ名(例: 'ignore previous instructions and...')でプロンプトインジェクションが成立し、AIが意図しない出力(個人情報漏洩・スコア改ざん)を返すリスクがある
🟥 Critical 📄 Dockerfile
Dockerイメージに.envが混入するリスク
Dockerfileで COPY . . を実行しており、.dockerignore が適切に設定されていない場合 .env(ANTHROPIC_API_KEY, GITHUB_TOKENを含む)がイメージレイヤーに焼き込まれる。イメージがDockerHubやRenderのレジストリに公開されると全APIキーが漏洩する
🟧 Warning 📄 app/Http/Controllers/ReviewController.php
fixエンドポイントにReviewオーナーシップ検証がない
ReviewController::fix は ip_hash の一致チェックなしに任意のReview IDを受け付ける。攻撃者が他人のReview IDでfixを繰り返しリクエストすると、そのレビューに紐づくリポジトリのGitHub APIコールとClaudeコールを消費させられる。レート制限はIPベースのみで Review の所有権を守っていない
🟧 Warning 📄 app/Services/GitHubService.php
GitHubServiceのparseUrlでSSRF的な入力が通過する
parseUrlは github.com を含むURLをregexで検出するが、例えば 'github.com.evil.com/owner/repo' のようなホスト名も $m[1]/$m[2] にマッチし得る。getRepoInfo等で使われるパスは /repos/{owner}/{repo} に限定されているためGitHub API以外への直接SSRFは発生しないが、不正なowner/repo文字列がDBに保存されUIで表示される際にパス操作や表示崩れのリスクがある
🟧 Warning 📄 .env.example
.env.exampleでAPP_DEBUG=trueがデフォルトのまま
.env.exampleのAPP_DEBUG=trueは開発者がそのままコピーして本番運用するケースで、スタックトレース・環境変数の一部がHTTPレスポンスに露出する。本番デプロイ時のミス設定を防ぐため APP_DEBUG=false をデフォルトにすべき
🟨 Suggestion 📄 app/Jobs/ProcessReviewJob.php
ProcessReviewJobでファイル取得エラーが黙って握り潰されている
foreach内のcatch(\Exception){}が空のため、特定ファイルの取得失敗がログにも残らない。重要なファイル(Dockerfile等)が403/404で取れなかった場合にレビュー品質が下がっても原因が追跡不可能になる
🟨 Suggestion 📄 app/Services/ClaudeReviewService.php
ClaudeReviewService::fixIssueのパース失敗時フォールバックが不完全
parseJsonが失敗した場合 ['before'=>null,'after'=>$text,'explanation'=>null] を返すが、$textにはClaude APIの生レスポンスが入りフロントエンドに丸ごと渡される可能性がある。beforeがnullのときUIがどう振る舞うかが不明で、エラーハンドリングの責任がコントローラ側に暗黙的に委ねられている
✅ 良い点
  • app/Http/Controllers/ReviewController.php の store メソッドが RateLimiter::hit + sha256(IP) で日次上限を実装しており、素のIPをDBに保存せずプライバシーに配慮している点が良い
  • app/Jobs/ProcessReviewJob.php が ShouldQueue + timeout/tries を明示しており、Claude API の遅延・タイムアウト時にキューが詰まらない設計になっている。failed() コールバックでDBステータスを確実に failed に更新している点も堅実
  • app/Models/Review.php の getOverallScoreAttribute / getScoreLabelAttribute / getScoreColorAttribute がアクセサとして集約されており、ビューでのスコア表示ロジックの重複を防いでいる

作り切ることが第一歩。改善を続けることがエンジニアリング。

🔧 リファクタ提案
  • ClaudeReviewService::buildReviewPromptとfixIssueのプロンプト構築ロジックを PromptBuilder クラスに切り出し、sanitizeInput適用・タグ囲みを一元管理することで、プロンプトインジェクション対策の抜け漏れを構造的に防ぐ
  • GitHubService::getFileContent内の1MB制限チェックを FileSizeGuard バリューオブジェクトに抽出し、selectKeyFilesのフィルタリングロジックと合わせてファイル選択戦略をStrategyパターンで差し替え可能にする(将来的なモノレポ対応に備える)
  • Review::getOverallScoreAttributeの計算式(3スコアの単純平均)をScoreCalculatorサービスクラスに移し、重み付け変更やスコアが1つでもnullの場合の扱いをテスト可能にする
🔒 セキュリティ注意点
  • ANTHROPIC_API_KEYとGITHUB_TOKENはDockerビルド時にARGではなく実行時の環境変数として注入するよう docker-entrypoint.sh とCI/CDパイプラインを設計すること。現状Dockerfileにシークレット注入の仕組みが明示されておらずイメージへの混入リスクが高い
  • GitHubService::getFileContentがbase64_decodeしたバイナリをそのままClaudeのプロンプトに渡す場合、バイナリファイル(画像・zip)が誤って選択されたとき不正なバイト列がAPIリクエストに混入する。拡張子ホワイトリストによるテキストファイル判定をselectKeyFiles内で強制すること
📤 PRコメント出力

このレビューをGitHub PRコメントとして貼り付けられるMarkdown形式で出力します。