2026-07-24 資安掃描修正 arc — 換 session Handoff

項目 內容
緣由 資安掃描修正 arc 主體已完成並經 user 手測驗收,context 滿了換 session。剩餘為 runner 派工、jedi-* 升版解殘留、CI/CD 化三條後續線
Branch BE / FE 皆在 main(未 push,見 §11)
接手前必讀 本文件全讀 → Notion 任務清單「資安掃描」相關 case
預估時間 依接手任務而定(見 §4 開工選項)

🧭 原始需求 / WHY

User(雷門)對 BE(compliance-manager-be)與 FE(compliance-manager-fe)跑了三工具資安掃描(semgrep / trivy / SonarQube),要求:分析報告 → 分診真偽 → 開 Notion case 追蹤 → 修正

目標狀態:HIGH 級漏洞歸零、憑證外洩處置完畢、剩餘項每條有明確歸屬(誰卡住、何時解)。此目標已在本 session 達成——本 handoff 的意義是把「剩餘三條後續線」與「本 arc 的環境知識」交給下一棒,不是接手修 bug。

大圖:這是 Guidant AI 產品的第一次系統性資安健檢。長期方向是把掃描常態化進 GitLab CI(secret gate 擋憑證、每週依賴健檢),本次手動掃描是 baseline。

§0 接手讀序

  1. 🔒 先懂需求:讀完本文件 🧭 + §1(成果總表)+ §3(剩餘工作),能答出下方自檢 4 問再動手
  2. Notion 任務清單(DB id 23c346da-4cd0-8041-955e-000bb6976dd2)搜「資安」——12 條 case 的即時狀態以 Notion 為準
  3. 若接 runner 派工線 → 讀 §3.1;若接 jedi 升版線 → 讀 §3.2;若接 CI/CD 線 → 讀 Notion CI case(內含完整架構與雷門準備清單)

冷接自檢:① 這個 arc 解決了什麼?(兩組憑證外洩 + 86 條 CVE + 程式碼硬化)② 為什麼還有 6 條 BE CVE 殘留?(jedi-* 硬 pin,需 user 明示才能動)③ commits 推了沒?(全部未 push)④ BE 正確啟動方式?(main_app.py port 8000,不是 main_socketio)

§1 本 arc 成果(已全部 user 驗收,Notion 標 Done)

掃描前後對比

指標 BE FE
Trivy HIGH 15 → 0 83 → 18(殘留=間接依賴+docs/reference 範本+preact)
Trivy 總計 26 → 6 202 → 35
Semgrep ERROR 38 → 預期歸零(未重掃複驗) 1 → 1(FE Dockerfile USER,待部署決策)
憑證外洩 2 組全部 revoke + 檔案清除

修正內容速覽

  • P0 憑證:Telegram token / Discord webhook(.env.sample/.env.test + conversation-history 15 檔)revoke + redact;FE sonar-project.properties 明文 admin 帳密移除(密碼已換,改 SONAR_TOKEN env var)
  • BE 硬化:報告 PDF 匯出 bleach sanitize(summary 是 TipTapEditor 富文本)、BPMN 解析 6 處改 defusedxml(產生端不動)、上傳檔名 secure_filename、classify Dockerfile 非 root、CORS config 化收斂(dev=* / stg+prod=[WEBSITE_URL])、分類器 job 目錄 /tmp→~/.cm-jobs(0o700)、workflow mapper 死碼修正(enum 透傳,不可 .value——下游 DTO 會再取一次)
  • BE 升版:pillow 12.3.0 / lxml 6.1.1 / weasyprint 68.1 / eventlet 0.40.4
  • FE 修正:camunda-api.js 死碼刪除(硬編內網 IP)、StorageConfigForm /tmp 預設改空 + 必填驗證接手
  • FE 升版:axios 1.18 / dompurify 3.4.12 / vite 4→8(+@vitejs/plugin-vue 6)/ overrides 7 套;xlsx 孤兒依賴移除
  • gitignore:兩 repo 加 .scannerwork/ + security-reports/
  • 裁決:quill 風險接受(3 表單、輸出全過 v-dompurify-html、被 PrimeVue 3.53 鎖 1.x)→ 根治歸「TipTap 收斂」case

§2 前次教訓(本 session 踩過的雷,別重蹈)

  1. BE 起服務用 main_app.py(port 8000)main_socketio.py 起的是 SOCKET_PORT 8002 非 API 入口——本 session 反覆起錯繞遠路。已寫 memory feedback_be_entrypoint_main_app_port_8000
  2. subagent 碰大檔必爆 contextdocs/conversation-history/security-reports/*.jsoncamunda_service.py(2000+ 行)、bpmn_generator.py(2300+ 行)。派工單必帶「禁 Read 整檔,grep -n 定位 + sed 看片段」護欄——A1 連死兩次都是這個原因
  3. 超長行檔案 grep 會靜默漏:conversation-history 有單行數萬字元的檔,plain grep 無錯誤無輸出直接跳過,要用 git grepgrep -a
  4. agent 的修正要獨立復核:A1 agent 把 mapper 改成 model.status.value,但下游 DTO(app/flow_engine/dto/ext_workflow_execution_dto.py:71)會再取 .status.value——盲收會讓所有 workflow 查詢炸 AttributeError。已改回 enum 透傳
  5. pytest test/ 目前整包壞:126 個 collection error(ModuleNotFoundError: No module named 'app'),是既有環境問題與本 arc 無關(stash 對照驗過)。BE 驗證改用煙測 + 起服務 + curl

§3 剩餘工作(三條線,皆記錄在 Notion)

§3.1 Runner 派工線(user 已同意方向,動工指引尚未寫入 case)

適合派 runner 自主處理的三條(user 拍板過「除 CI/CD 外可派 runner」):

  • FE Sonar 品質債(Notion「[優化] FE Sonar 品質債 backlog」):a11y ~240 條按元件群分批 + 2 CRITICAL bug。⚠️ AppMenuItem.vue 那條必須先讀 source 再動(memory feedback_appmenuitem_manual_verify,側邊選單高亮敏感區)
  • BE Sonar 品質債(Notion「[優化] BE Sonar 品質債 backlog」):只派安全桶(未用變數 42 / 未用參數 83 / 註解碼 66 / 重複字面值 62)。⚠️ 禁區:S3776 認知複雜度 207 條(重構有語意風險)+ BLOCKER S3516 7 條(FR-038 stub 一族,盲修出事)。且 BE 無測試安全網(§2.5),驗證只能靠 main_app 起得來 + 煙測
  • TipTap 編輯器收斂(Notion「[優化] 富文本編輯器收斂到 TipTap」):3 個 quill 表單換現成 TipTapEditor.vue → 拔 quill + ckeditor5。做完標「修正待驗證」等 user 手測,不自動關

下一棒動作:把各 case 補「🔧 Runner 動工指引」段(分批策略 / 禁區 / 驗證命令 / commit 規範)再派。 小件未做:FE preact 補升(direct dep、HIGH CVE-2026-22028、目標 10.28.2)——一行 + build 驗證,可順手做。

§3.2 jedi-* 升版解殘留線(需 user 明示才動)

BE 殘留 6 條 CVE 中 4 條被 jedi-* 硬 pin 卡住: | 套件 | 卡住來源 | 目標 | |------|---------|------| | flask 3.1.0 | jedi-common==0.0.27 pin Flask==3.1.0 | 3.1.3(LOW ×2) | | marshmallow 3.23.2 | jedi-common pin | 3.26.2(MEDIUM,留 3.x) | | python-dotenv 1.0.1 | jedi-oscal-v2==2.2.1 pin | 1.2.2(MEDIUM) | | pytest 8.3.4 | jedi-oscal-v2 pin | 8.4+(MEDIUM,dev 工具) |

流程走 jedi-package-dev skill(path dependency dev → user 明示才發版推 Nexus)。另 2 條無解殘留:weasyprint CSS injection(上游 no-fix)+ flask 已含在上表。

§3.3 CI/CD 線(等雷門環境準備)

Notion「[資安][基礎建設] 資安掃描進 GitLab CI」case 內含完整三層架構(gitleaks MR gate / trivy+semgrep 排程 / sonar)與雷門準備清單(runner 確認 / CI variables / SonarQube 搬家決策 / gate 嚴格度)。等 user 說準備好了再實作。

§4 開工順位(下一棒依 user 指示擇一)

  1. user 指定接哪條線 → 讀對應 §3.x → 開工
  2. 若接 runner 線:先補 case 動工指引 → 等 user 確認 → 派工
  3. 任何 BE 驗證:main_app.py + port 8000 + /api/1.0/login 空 body 回 400 = 正常

§5 該讀的檔案

  • Notion 任務清單(狀態真相源):DB 23c346da-4cd0-8041-955e-000bb6976dd2
  • 掃描報告(已 gitignore,勿 Read 整檔,jq 查詢):兩 repo security-reports/(本 session 結束時為修正後重掃版)
  • BE 掃描腳本:scripts/sonar_scan.sh(SONAR_TOKEN 走環境變數;hotspots API 需 squ_ User Token,SONAR_USER_TOKEN 也在 ~/.zshrc)

§6 Pre-flight(接手必跑)

cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
git log --oneline -8   # 應見 9fb4a111 / 15d19e3a / 92145244 / 44aa0459 / f0a951eb / 88f33699 / 99ff37af
git status --short     # 應乾淨(untracked 不算)
cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe
git log --oneline -6   # 應見 7e4030a / 3c5b411 / d404e3a / eb7fa8a / f3eca51 / c60dbde
git status --short

§7 Verify 本 arc 確實 close

User 已手測驗收(2026-07-24 深夜):FE dev server(vite 8)+ HMR + 頁面正常;BE main_app 起動 + 登入 + PDF 匯出。Notion 6 條修正 case 全標 Done。複驗可跑:

# 憑證歸零
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
for p in 7947959693 1366089469018767493 860100307; do grep -ral "$p" . --exclude-dir=.git --exclude-dir=security-reports --exclude-dir=log; done  # 應無輸出
# trivy 殘留(應 BE 6 條 / FE 35 條)
jq '[.Results[].Vulnerabilities // [] | .[] | .Severity] | group_by(.) | map({sev: .[0], count: length})' security-reports/trivy-backend.json

§8 行為規範重要提醒

  • 不切 branch / 顯式 git add 禁 -am / push 永遠等 user 明示(目前 13 commits 未 push)
  • BE 起服務 = main_app.py(8000);改 service code 必重啟(kill -9)
  • jedi-* 異動需 user 明示;發版絕不自動推 Nexus
  • 派 subagent 必帶大檔護欄(§2.2)+ 顯式 git add 警語
  • user 說「先不用/等等」就停手,不搶跑

§9 收尾流程

本 arc 主體已收(Notion Done ×7 含 xlsx/quill 討論條)。若後續線完成:對應 case 標「修正待驗證」→ user 驗 → Done。spec 更新不適用(資安修正非頁面行為變更;CORS/儲存設定行為若日後被問,代碼註解已足)。

§10 不在本期 scope

  • FE Dockerfile nginx USER(涉 port 映射,等部署決策)
  • FE lockfile 不入版控問題(既有慣例,動它牽 CI,留給 CI case 一起考慮)
  • BE pytest 環境修復(126 collection errors,值得開 case 但未開)
  • git history rewrite 清歷史憑證(已 revoke,成本不值)

§11 本 session commits(全部未 push)

BE(7 commits)

9fb4a111 fix(security): BE 依賴安全升版——pillow 12.3/lxml 6.1/weasyprint 68/eventlet 0.40(Trivy 26 CVE 修復)
15d19e3a fix(security): Sonar 安全項——CORS 收斂 config 化、分類器 job 目錄脫離 /tmp、workflow mapper 死碼修正
92145244 fix(security): 程式碼硬化——報告 XSS sanitize、BPMN 解析改 defusedxml、上傳檔名 secure_filename、classify Dockerfile 非 root
44aa0459 chore(gitignore): 排除 security-reports/
f0a951eb chore(gitignore): 排除 .scannerwork/
88f33699 fix(security): 憑證清理補漏 1 檔(超長行 grep 靜默漏掉那檔)
99ff37af fix(security): 憑證清理主體(.env.sample/.env.test + conversation-history 14 檔)

FE(6 commits)

7e4030a fix(security): 移除未使用的 xlsx 依賴
3c5b411 fix(security): 依賴安全升版——axios/dompurify/vite 等
d404e3a chore(gitignore): 排除 security-reports/
eb7fa8a chore(gitignore): 排除 .scannerwork/
f3eca51 fix(security): sonar-project.properties 移除明文 admin 帳密
c60dbde fix(security): camunda-api 移除硬編內網位址、儲存設定 local 路徑預設脫離 /tmp

部署注意:classify docker image 需各主機 rebuild(Dockerfile 加了 USER);分類器 job 目錄換位置,部署環境 -v 掛載路徑需同步。

§12 給 fresh session 的超短 prompt

請讀 docs/features/security-scan-2607/handoff/2026-07-24-security-scan-arc-session-handoff.md,
先答出 §0 冷接自檢 4 問(不要跳過 WHY),再跑 §6 pre-flight。
本 arc 主體已完成驗收,你的工作是接剩餘線(§3):等我指定接哪條再動工。
注意:BE 起服務用 main_app.py(port 8000);所有 commits 未 push,push 等我明示。