スクリーンショット修正リリースで Django の CVE も検知し、証跡化まで自動化した話
今回のリリースのきっかけは、マニュアル用に採取したスクリーンショットでした。画面の中にIPアドレスやメールアドレスが混じったままになっていたので、それを外に出しても問題ない形に直すためのリリースです。 それとともに、CIでのセキュリティスキャンが機能したので、どう機能したのかについてお話ししようと思います。
メールアドレスはデモ用のものなので、実害がある類のものではありません。ただ、マニュアルやスクリーンショットは一度外に出ると広がりやすいので、IPアドレスやメールアドレスのような情報が写り込んでいるかどうかは、きちんと確認したほうがいいところです。
もちろん、これもセキュリティリスクに関わる対応なので、risk-assessor に渡して証跡として記録しました。さらに今後の対応として、スクリーンショットを採取したときに、メールアドレス、IPアドレス、その他外部に露出させるべきではない情報が含まれていれば、マスク処理をしたものを採用する、というルールをエージェント側にも記憶させています。
GenbaFlow では、リリース時の GitHub への push をきっかけに、GitHub Actions でセキュリティスキャンを実行するようにしています。今回はこのリリースの過程で、CI に組み込んでいる pip-audit が Django 6.0.4 に対して3件の脆弱性を検出しました。
そこから Django 6.0.5 へのアップグレード、リスク台帳への登録、レビュー、リリースまでを、エージェントに役割分担させて対応しました。
大事なのは、単に「スクリーンショットを差し替えた」「依存パッケージを上げた」ことではありません。検知後の判断、修正、レビュー、リスク評価、リリース記録までを決まった流れにしておくと、ISO27001/ISO27005 で必要になる証跡も自然に残ります。
このあたりを毎回手作業でそろえるのは、正直かなり面倒です。だからこそ、LLMエージェントの役割として最初から定義しておくと、ISO対応を日々の開発作業の中に入れやすくなります。
何が起きたか
master への push をトリガーとした GitHub Actions の security-scan ジョブが失敗しました。ログを確認すると、pip-audit が以下を報告していました。
Found 3 known vulnerabilities in 1 package
Name Version ID Fix Versions
------ ------- ------------------- ------------
django 6.0.4 GHSA-7h2m-m8vj-598h 5.2.14,6.0.5
django 6.0.4 GHSA-5hrc-gvxj-w55p 5.2.14,6.0.5
django 6.0.4 GHSA-w26r-rmm8-9c29 5.2.14,6.0.5
修正バージョンは Django 6.0.5。3件の内訳は次の通りです。
| GHSA | 種別 | CVSS |
|---|---|---|
| GHSA-7h2m-m8vj-598h | セッション固定・セッション盗用 | Low / 2.3 |
| GHSA-5hrc-gvxj-w55p | キャッシュ経由のプライベートデータ露出 | Low / 2.3 |
| GHSA-w26r-rmm8-9c29 | ASGI DoS・メモリ枯渇 | Moderate / 6.3 |
対応の流れ
GenbaFlow では、セキュリティ対応をエージェント間の役割分担で進めています。今回も「検知した人が、その場の判断で全部やる」のではなく、あらかじめ決めた担当に処理を渡す形で Claude Code を設定してあります。
こうしておくと、作業の抜け漏れを減らせます。それだけでなく、あとから監査やレビューをするときに必要な材料もそろいます。検知ログ、修正コミット、テスト結果、リスク台帳、レビュー指摘、リリース記録が、それぞれ別の成果物として残るからです。
加えて、サブエージェントに作業を分けられるので、メインのコンテキストを使いすぎずに済みます。地味ですが、長めの対応ではかなり効きます。
1. ci-engineer がアップグレードとテストを担当
requirements.txt の Django==6.0.4 を Django==6.0.5 に変更し、Dockerコンテナ内でテストスイートを実行。9件全件グリーンを確認してコミットしました。変更はこの1行のみで、他のパッケージには触れていません。
2. risk-assessor がリスク台帳に登録
3件の GHSA を1エントリ(RISK-020)としてまとめて ISO27005 リスク台帳に登録しました。同一パッケージ・同一 fix バージョンの複数 CVE を単一エントリに統合する方針は、過去の RISK-016(expat 複数 CRITICAL CVE)で確立済みの先例に従っています。
GHSA-w26r-rmm8-9c29(ASGI DoS)については、GenbaFlow の本番環境が Gunicorn(WSGI)であるため攻撃ベクターが適用されないと判断し、impact: 2 を維持する根拠として notes に明記しました。
ここは ISO27005 的には大事なところです。単に「修正しました」で終わらせず、脆弱性をどう評価したのか、どのリスクとして扱ったのか、なぜその影響度にしたのかを残しています。ISO27001 の管理策運用として見ても、変更管理・脆弱性管理・リスク対応の証跡を同じ流れの中で残せます。
3. reviewer がコードとドキュメントをチェック
レビュー結果は「軽微な問題あり承認」。指摘は3件でした。
docs/project_map_archives.mdの Django バージョン記載が6.0.2のまま(中優先度)RISK-020.mdのcategoryがintegrityで不正確(正しくはconfidentiality, availability)notesの「コミット済み・未push」という記述がプッシュ後に事実と乖離する
いずれも修正してリリースに進みました。
4. release-manager が v4.21.2 をリリース
Django アップグレード、ドキュメント修正、リスク台帳登録をまとめて v4.21.2 としてリリースしました。リリース作業では private リポジトリの接続情報を扱うため、記事上では具体的なリポジトリ URL や内部パスは伏せています。
検知から完了までの時系列
| # | 作業 | 担当 |
|---|---|---|
| 1 | GitHub Actions の security-scan が失敗 → ログでDjango CVE 3件を特定 | CI |
| 2 | requirements.txt を 6.0.5 に変更・テスト実行(グリーン)・コミット | ci-engineer |
| 3 | RISK-020 を ISO27005 リスク台帳に登録 | risk-assessor |
| 4 | コードレビュー → 3件の指摘 | reviewer |
| 5 | project_map_archives.md と RISK-020.md を修正 | claude |
| 6 | v4.21.2 リリース(コミット・タグ・push・GitHub Release) | release-manager |
ISO対応であとから助かる記録
今回の対応では、セキュリティ対応を進める中で、次の記録が残りました。
- CI の失敗ログ:脆弱性をいつ、どの検査で検知したか
- 依存関係の修正コミット:何を、どのバージョンへ変更したか
- テスト結果:変更後に主要機能が通っているか
- RISK-020:脆弱性をどのリスクとして見て、どう扱ったか
- レビュー指摘と修正:分類や記述の妥当性を第三者視点で確認したか
- リリース記録:いつ、どの単位で本番反映可能な状態にしたか
この一式があると、あとから「なぜこの対応で十分と判断したのか」を説明しやすくなります。ISO27001 の監査では、ルールを作っているかだけでなく、そのルールに沿って実際に動いているかも見られます。エージェントを役割ごとに用意しておくと、その記録が作業の途中で自然に残るのが助かります。
やってみてわかったこと
ASGI DoS(GHSA-w26r-rmm8-9c29)の判断は、今回整理できてよかった点です。CVSS 6.3 の Moderate CVE がスキャンで出ると、数字だけ見れば少し気になります。ただ、GenbaFlow は WSGI(Gunicorn)で動いているため、ASGI を対象とした攻撃ベクターは実環境では成立しません。この判断根拠を notes に明記したので、あとから監査や見直しをするときも経緯を追えます。
reviewer が category: integrity の誤りを指摘した点も、自動化に任せきりにしない理由がよく出ています。risk-assessor がドラフトを作り、reviewer が別の目で確認する形にしておくと、こういう分類ミスを拾えます。
エージェント化すると、属人化しやすい判断を手順にしやすい点も確認できました。ASGI/WSGI の適用可否や、複数 CVE を1つのリスクにまとめるかといった判断は、毎回ゼロから考えるとぶれやすいところです。そこを risk-assessor、reviewer、release-manager に分けておくと、判断の根拠と確認者がはっきりします。
まとめ
今回の対応は、エージェントへの指示、確認、修正を含めても短い時間で完了しました。pip-audit を CI に組み込んでいたので検知は自動化されていて、その後の対応も事前に決めていた流れに沿って進みました。
CVE が出るたびに手動で全工程を進めるのは、小規模なチームほど負担になります。「検知 → 調査 → 修正 → 台帳記録 → レビュー → リリース → 証跡化」の各ステップを役割として分け、それぞれに適切なエージェントを当てておくと、誰が担当しても同じ品質で対応しやすくなります。
ISO27001/ISO27005 対応は、分厚い規程を作るだけでは現場に定着しません。日々の開発フローの中で、必要な判断と記録が自然に残る形にしておくことが大切です。今回のようなエージェント構成は、そのためのかなり現実的なやり方だと感じています。