1. セキュリティ監査の実施
iso_app (建設アシスト)のセキュリティ強化を実施する
1.1 監査方法
Claude Code(Opus 4.7)を「セキュリティ監査員」として起用し、以下の観点でアプリケーション全体を調査しました。
- 認証・認可の漏れ(全コントローラーを網羅的に調査)
- テナント分離の実装状況(マルチカンパニー対応の確認)
- ファイルアクセス制御
- AI API への機密情報送信リスク
- 入力検証・出力エスケープ
- 依存ライブラリの脆弱性
1.2 監査サマリー
| 重大度 | 件数 | 対応状況 |
| Critical | 6件 | 4件完了・2件対応中 |
| High | 8件 | 7件完了・1件対応中 |
| Medium | 2件 | 計画中 |
| 合計 | 16件 | 11件完了 |
3. High 項目の詳細
| 項目 | コントローラー | 内容 | 状態 |
| 認可漏れ | ChecklistController | getEvidence で他社データをJSON取得可能 | ✅ 完了 |
| 認可漏れ | EnvironmentController | index/edit/save/aiEstimate でテナント確認なし | ✅ 完了 |
| 認可漏れ | RiskAssessmentController | downloadAttachment で他社ファイルダウンロード可能(16メソッド) | ✅ 完了 |
| AI情報 | AuditAiService | 被監査対象名・業務概要がAPI送信される | ⚠ 対応中 |
| AI情報 | SafetyPatrolController | 作業内容・使用機械の詳細が送信される | ⚠ 対応中 |
| AI情報 | risk_assessment.blade.php | 下請業者名・プロジェクト名がプロンプトに含まれる | ⚠ 対応中 |
4. 是正処置の内容
4.1 共通トレイトの新規作成
認可ロジックを一元化する AuthorizesTenantAccess トレイトを作成しました。
app/Http/Controllers/Concerns/AuthorizesTenantAccess.php
このトレイトにより:
- 認可ロジックが1箇所で管理される
- 各コントローラーへの適用が use 一行で済む
- 将来の Policy 移行への布石となる
- 役割ベースの例外(システム管理者は全社アクセス可)を正しく処理
4.2 適用したコントローラーと保護されたメソッド数
| コントローラー | 保護メソッド数 | 対応回 |
| ProjectController | 8メソッド | 第1回 |
| ConstructionPlanController | 15メソッド | 第1回 |
| SafetyPatrolController | 14メソッド | 第1回 |
| ChecklistController | 6メソッド | 第1回 |
| EnvironmentController | 4メソッド | 第2回 |
| RiskAssessmentController | 16メソッド | 第2回 |
| 合計 | 63メソッド | ー |
4.3 テストケース(26件 全PASS)
各コントローラーに対して以下のパターンを網羅的にテスト:
- 他社ユーザーが各リソースにアクセス → 403
- 自社ユーザーがアクセス → 200(正常)
- role=1 システム管理者 → 全社アクセス可(200)
- 削除・変更系でDBの状態が変わらないことを確認
4.4 実施コストと効果
| 項目 | 内容 |
| 実施時間(合計) | 約2時間半 |
| API利用コスト | $6.51(約1030円) |
| 外注した場合の市場価格 | 130〜350万円相当 |
| コスト比 | 約1300〜3500倍の費用対効果 |
| コード変更量 | 673行追加、12行削除 |
| テスト件数 | 26件 全PASS |
2. Critical 項目の詳細
2.1 テナント分離の欠落(Critical 1〜4) ✅ 完了
最も重大な問題でした。URL のIDを変えるだけで他社のデータに読み取り・編集・削除アクセスが可能な状態でした
| 対象コントローラー | 影響範囲 | 重大度 |
| ProjectController | show/edit/update/destroy/editOverview/updateOverview/uploadPhoto(8メソッド) | Critical |
| ConstructionPlanController | downloadDocx/downloadXlsx/generatePdf/diagramEditor等(15メソッド) | Critical |
| SafetyPatrolController | create/store/index/show/destroy/generateAiChecklist等(14メソッド) | Critical |
| ChecklistController | deleteEvidence/getEvidence等(6メソッド) | Critical |
2.2 AI API への機密情報送信(Critical 5〜6) ⚠ 対応中
発注者名・予算・下請業者名・近隣企業名などが、マスキングなしで Anthropic Claude API に送信される可能性がありました。
【現状の評価(設計意図の確認後)】
現状のAI利用は「チェックボックス選択による固定語彙のみを送信」という設計になっており、実質的な機密情報漏洩リスクは低い状態です。ただし、将来の機能拡張で誰かがフリーテキストを送る実装をしてしまうリスクの予防として、コードレベルのガード機構を実装予定です。
5. 進捗状況
| フェーズ | 内容 | 状態 |
| Phase A | リスクアセスメント(自主監査) | ✅ 完了 |
| Phase B-1 | Critical 1〜4 テナント分離 | ✅ 完了 |
| Phase B-2 | High 7〜9 認可漏れ(Environment, RiskAssessment) | ✅ 完了 |
| Phase B-3 | Critical 5〜6, High 10〜12 AI関連 | ⏳ 次フェーズ |
| Phase B-4 | Medium 13 ファイル名処理 | ⏳ 後ほど |
| Phase C | AIゲートウェイ構築・匿名化 | 📅 来月 |
| Phase D | 監視・運用体制の確立 | 📅 数ヶ月後 |
| Phase E | 継続的改善(PDCA) | 継続 |
6. 次フェーズの計画
6.1 AI送信情報のガード機構(InputValidator)
現在の「固定語彙のみ送信」という設計意図をコードで強制するバリデータークラスを実装します。
- 会社名・個人名らしき文字列の検出
- 長い数字列(電話番号・契約番号等)の検出
- 検出時の警告ログ記録
- 既存のAI Serviceへの組み込み(5箇所)
6.2 将来計画:ローカル AI 前処理
契約事項・技術的背景・経営内容の文書化を扱う際、自前サーバーに置いたローカルAIで一般化処理をしてから外部AIに送信する仕組みを構築予定です。
- ルールベース匿名化サービス(Phase 1): 氏名・会社名・金額の自動マスキング
- ローカルLLM検証(Phase 2): Ollama + Llama 3.2 などで自前AIの感触をつかむ
- 統合AIゲートウェイ(Phase 3): 匿名化→外部AI→復元のパイプライン構築

