F1.セキュリティ検証レポート(フェーズ1)
F1-1.検証規模
コントローラ: 約40ファイル / モデル: 約50ファイル / Blade: 約168ファイル / ルート: 3ファイル / サービス: 8ファイル
検証観点: A テナント分離 / B 認証・認可 / C 入力検証・インジェクション / D XSS / E CSP / F CSRF・セッション / G ファイルアップロード / H 情報漏洩 / I 依存パッケージ
F1-2.指摘件数(重大度別)
数 主な内容 Critical 7 クロステナント IDOR 群(工程表・安全パトロール・RA・施工計画書)、CSP unsafe-inline + 保存型XSS の複合、phpspreadsheet SSRF/RCE High 12 テンプレート認可欠落、機密ファイルの public 保存、保存型XSS(図面/AI-HTML/style属性)、依存パッケージ High、-tmp/_old ファイルのオートロード混入 Medium 15 Mass Assignment、例外メッセージ露出、グローバルマスタ越境、パストラバーサル、Secure Cookie 未設定 等 Low 多数 多層防御・推奨改善(代表例+件数で集約)
F1-3.総評
全モデルにテナント用グローバルスコープ(BelongsToTenant 等)が存在せず、テナント分離は各コントローラの手動 authorizeProject() に全面依存している。
そのうえ authorizeProject() は「Project が自社か」しか見ず、ネストした子リソース(schedule / patrol / riskAssessment / item)の親一致を検証していない メソッドが多数あり、Route::scopeBindings() も未使用。結果として「自社の Project ID + 他社の子リソース ID」を URL に並べるだけで他テナントのデータを閲覧・改ざん・削除できる Critical な IDOR が7系統 存在する。
加えて CSP に script-src ‘unsafe-inline’ が残存し、図面ノード・AI整形HTMLがサーバー側サニタイズなしで保存・再表示 されるため、保存型XSSが現実的に成立する。
一方で、認可が正しく実装されているコントローラ群も多く (ProjectPlan / Audit 系 / CompanyAdmin など)、修正パターンは「authorizeProject() の追加 + 子リソースの親一致 abort_if の2行」と明確です。恒久対策として Route::scopeBindings() の全面適用とグローバルスコープ導入を行えば、監査耐性は大きく向上します。
F2.保守性・改善提案レポート(フェーズ2)
F2-1.テナント設計の未完了モデル洗い出し
重要な前提 : 本アプリには BelongsToTenant 相当のグローバルスコープ(addGlobalScope)は1つも存在しない 。テナント分離はすべてコントローラ内の手動 where(‘company_id’, …) / authorizeProject() に依存している。既存の booted()(BarTask / NetworkNode / NetworkArrow)は front_id(UUID)採番専用でスコープではない。したがって下表の「グローバルスコープ」列は全モデル「未実装」。
テナント到達経路: 子テーブルは company_id を持たず、project_id → projects.company_id(または schedule_id → schedules.project_id、audit_report_id → audit_plans.company_id 等)の多段リレーションでのみテナントを特定できる。
F2-2.観点: 重複コード
【高】Anthropic API 呼び出しの8重複(CLAUDE.md「AI推論は共通コード」ルール違反)
【高】テナント認可の二重方式(トレイトがあるのに手書きが残存)
【中】★ CSV入出力ロジックの6重複
【中】Docx/Xlsx出力の二系統併存(デッドコードの懸念)
【中】フロントエンド fetch/CSRF/モーダル制御の重複
F2-3.観点: 肥大化
コントローラ行数 Top10(実測)
数 ファイル 1548 ConstructionPlanController.php 952 ProjectPlanController.php 865 NetworkScheduleController.php 687 SafetyPatrolController.php 573 EnvironmentController.php 432 RiskAssessmentController.php 392 BarChartController.php 350 ChecklistController.php 313 UserController.php 251 CompanyAdminController.php
【高】Blade巨大ファイル(インラインJS肥大)
数 ファイル 特記 3082 schedules/network.blade.php 単一<script> が724-3080の約2356行 2439 schedules/barchart.blade.php 同様の巨大インラインJS 1875 projects_plan/edit_section.blade.php @push(‘scripts’)+diagram-editor-script include+openCtxMenu上書きIIFE 854 environment/edit_environment.blade.php 729 projects_plan/setup.blade.php 対応 setup.js(392行)は分離済み=良い前例
提案 : network / barchart の巨大インラインJS を resources/js/schedules/network.js・barchart.js に外部化(setup.js の前例に倣う)。CSP unsafe-inline 除去の前提条件でもある。
想定作業量 : 大 → 別途計画が必要
【中】SVGダイアグラムエディタ群(実測 計4172行)の再分割 既に責務別5分割済み(良い設計)だが個別ファイルが肥大:
数 ファイル 責務 1541 diagram-editor-nodes.blade.php ノードCRUD/RTB/画像/線ノード 1132 diagram-editor-table.blade.php 表/Excel貼付/xspreadsheet 726 diagram-editor-ui.blade.php 右クリック/保存/ページ/テンプレ/印刷 602 diagram-editor-connect.blade.php コネクタ/接続線ダイアログ 154 diagram-editor-core.blade.php 状態/Undo-Redo/グリッド