0
✦ 品質
🛡 セキュリティ
⚙ 保守性
📋 概要
Ruby on Rails 7.2製のAI思考整理ツール。ユーザーが悩みを入力するとClaude APIがエラーログ風に分析し、SSEでリアルタイムストリーミング表示する単機能Webアプリ。
🎯 今すぐ直すべき3点
-
app/controllers/debug_logs_controller.rb Strong Parametersのdebug_log_paramsメソッドが確認できないため、inputフィールドに対してpermit(:input)を明示したStrong Parametersを実装し、入力長の上限バリデーション(例: validates :input, length: { maximum: 2000 })をDebugLogモデルに追加する↗
-
app/controllers/debug_logs_controller.rb showアクションでDebugLog.find(params[:id])を直接呼び出しており認可チェックが皆無。悪意あるユーザーが全ログをIDスキャンで閲覧可能なため、少なくともip_hashによる所有者確認、またはトークンベースのアクセス制御を実装する↗
-
config/initializers/rack_attack.rb(未確認) Gemfileにrack-attackが存在するが、実際のthrottle設定ファイルが提供されていない。/debug_logsへのPOSTに対して1IP/分あたり5リクエスト程度のレート制限ルールを明示的に設定し、Claude API費用爆発を防ぐ↗
🔍 検出された問題 (8件)
🟥 Critical
📄 app/controllers/debug_logs_controller.rb
全DebugLogが認可なしに公開アクセス可能
debug_logs_controller.rbのshowアクションはDebugLog.find(params[:id])のみで認可チェックが存在しない。連番IDをインクリメントするだけで他ユーザーの悩み内容(inputフィールド)が全件閲覧可能であり、個人情報漏洩に直結する。ip_hashは保存されているが照合に使われていない。
🟥 Critical
📄 app/controllers/debug_logs_controller.rb
入力バリデーションの欠如(Strong Parameters未確認・長さ制限なし)
debug_log_params実装が提供コードに見当たらず、inputフィールドの長さ制限もdb/schema.rbのtext型定義にもモデルにも存在しない。無制限の長文入力がClaude APIに送信されるとmax_tokens超過・API費用爆発・DoSに繋がる。
🟥 Critical
📄 config/initializers/rack_attack.rb
rack-attackの実設定が未確認でレート制限が機能していない可能性
Gemfileにrack-attackは存在するが、config/initializers/rack_attack.rbの内容が提供されておらず、throttleルールが実際に設定されているか不明。設定なしではgemを入れても無効であり、Claude API呼び出しを無制限に行われると費用が青天井になる。
🟧 Warning
📄 app/controllers/debug_logs_controller.rb
streamアクションのエラーハンドリングが不完全(コードが途中で切れている)
debug_logs_controller.rbのstreamアクションのrescue => e節がファイル末尾で切断されており、汎用例外時のSSEエラー送信・ストリームクローズ処理が完結しているか確認できない。SSEストリームが閉じられないとサーバースレッドがリークする。
🟧 Warning
📄 app/controllers/debug_logs_controller.rb
LLMレスポンスのJSONパースエラー時にフォールバック値が固定値で返却される
JSON::ParserError時にseverity: 50等の固定値サマリーを返しているが、raw_jsonをoutputに保存した上でユーザーには成功レスポンスを返すため、破損データがDBに蓄積される。エラーをユーザーに明示し、DBへの保存をスキップすべき。
🟧 Warning
📄 test/
テストが実質存在しない
Gemfileにcapybara・selenium-webdriverは含まれるが、テストファイルが一切提供されておらず、DebugLogGeneratorのプロンプトインジェクション対策・SSEストリーム・バリデーションの動作保証がない。将来のリファクタ時に無音で壊れるリスクがある。
🟧 Warning
📄 config/environments/production.rb
config/production.rbでconfig.require_master_keyがコメントアウト
config/environments/production.rbの`config.require_master_key = true`がコメントアウトされており、RAILS_MASTER_KEYが未設定でも起動してしまう。credentials内のシークレット(APIキー等)が復号されないまま動作し、サイレントな設定ミスを見逃す。
🟨 Suggestion
📄 app/javascript/controllers/stream_controller.js
stream_controller.jsのdetectCategoryメソッドが途中で切断されている
提供されたapp/javascript/controllers/stream_controller.jsがdetectCategory関数の途中で終わっており、カテゴリ検出ロジックの全容が不明。フロントエンドのビジネスロジックがJSファイルに集中しており、テスト不可能な状態になっている。
✅ 良い点
- app/services/debug_log_generator.rb のsanitized_inputメソッドが<user_worry>タグのエスケープを行い、かつSYSTEMプロンプトでタグ内はデータとして扱う旨を明示しており、Prompt Injectionへの多層防御が意識されている
- Gemfile にrack-attack、brakeman、rubocop-rails-omakaseが含まれており、セキュリティ・静的解析ツールチェーンが最初から組み込まれている
- Dockerfile でRAILS_ENV=productionとBUNDLE_WITHOUT=development:testを明示し、dev/testジェムが本番イメージに混入しない設計になっている
🔧 リファクタ提案
- app/controllers/debug_logs_controller.rbのstreamアクション(SSE設定・JSON解析・DB更新・エラーハンドリング)をapp/services/DebugStreamService等に切り出し、コントローラを薄くする
- app/services/debug_log_generator.rbのpromptメソッドをERBテンプレートまたは別ファイルに分離し、プロンプト文字列とRubyロジックを混在させない
- db/schema.rbのdebug_logsテーブルにcreated_atインデックスを追加し、view_count降順クエリ(popular取得)にもインデックスを貼ってN+1・フルスキャンを防ぐ
🔒 セキュリティ注意点
- app/services/debug_log_generator.rbのPrompt Injection対策(タグ隔離+systemプロンプト明示)は適切だが、sanitized_inputが<user_worry>タグのみを除去しており、他のXML/HTMLタグやClaude特有のマジックトークンへの対策は未実施
- debug_logs_controller.rbのip_hashはSHA256(remote_ip)で生成されているが、IPv4アドレス空間は約43億通りしかなくレインボーテーブルで逆引き可能。ソルト付きハッシュ(例: SHA256(salt + ip))に変更すべき
📤 PRコメント出力
このレビューをGitHub PRコメントとして貼り付けられるMarkdown形式で出力します。