security-scan · 需求索引 · 本頁由 build 掃資料夾生成
彙整報告,2026-09-09 產出、2026-09-10 併入 FR-081 六棒收口。掃描結論、修正卡狀態、未開卡待辦、覆蓋率地圖四合一。每棒驗收完由首腦同步更新
這份檔在回答一個問題:掃了那麼多,結論是什麼、還有哪些要修。 六個掃描 arc 的報告各自在自己的 FR 資料夾,這裡只做跨 arc 收斂——不重複細節,每條都給座標。 逐條技術細節請點各棒報告;現況與派工紀律看
FR-075/handoff/security-scan-STATE.md。
CM-1595(遠端 Agent 控制面四端點完全不驗身分,CRITICAL,免登入即可取走客戶機器的明文憑證)。它「沒派」是決策者裁定「PM 統一安排修正」的結果,不是漏掉。jedi-common(全部套件的地基)至今沒有一次算數的掃描。.env.test/JWT 金鑰/DB 密碼 249 檔)。修法可以抄,但要治本得改工作方式。| Arc | 對象 | 棒 | 結果 | 報告 |
|---|---|---|---|---|
| FR-075 | jedi-iam(290 檔/7 棒) | S1 認證與外部身分 | ✅ 8 條(5H 3M) | 報告 |
| S2 授權守門 | ✅ 0 條(首腦仍加開 CM-1559) | 報告 | ||
| S3 MFA+Turnstile | ✅ 2 條(1H 1M) | 報告 | ||
| S4 使用者與密碼 | ✅ 5 條(2C 1H 2M) | 報告 | ||
| S5 角色與權限 | ✅ 2 條(2M) | 報告 | ||
| S6 租戶與組織 | ✅ 1 條(1M)+3 條非資安真 bug | 報告 | ||
| S7 登入態/middleware | ⚠️ 無效——9 條裡 8 條越界重複 S1,核心範圍從未被掃 | 報告 | ||
| FR-076 | License 鏈(118 檔/4 棒) | L1 驗章核心 | ✅ 1 條範圍內 HIGH(解壓炸彈) | 報告 |
| L2 授權狀態 API | ✅ 1 LOW +人工另發現 1 HIGH(停權可換照解除) | 報告 | ||
| L3 LC 簽發核心 | ✅ 1H 1M(序號僅 32 bits/log 遮蔽失效) | 報告 | ||
| L4 LC 網頁後台 | ✅ 4M(開通端點防猜失效、開放導轉) | 報告 | ||
| FR-077 | 遠端 Agent(⏸ 暫停) | R1 agent 身分與註冊 | ⚠️ 7 條(1C 2H 3M 1L),面板全滅、覆蓋率不可宣稱 | 報告 |
| R1b/R2a/R2b/R3 | ⬜ 卡開好、範圍寫死,未派 | — | ||
| FR-078 | jedi-notification | N1 套件本體 | ✅ 2 條(2M,SMTP 密碼進 log/starttls 不驗憑證) | 報告 |
| N2 宿主接線 | ✅ 6 條(2H 3M 1L,其中 4 條範圍外憑證) | 報告 | ||
| FR-079 | jedi-bulletin | B1 套件本體 | ✅ 工具 0 條+人工 3 條(皆目前打不到) | 報告 |
| B2 宿主接線 | ✅ 10 條(4 條範圍內、6 條範圍外憑證) | 報告 | ||
| FR-081 | jedi-issue(158 檔/6 棒) | I1 第三方整合與憑證(25 檔) | ✅ 2 條(連 GitHub 不驗憑證) | 報告 |
| I2 宿主接線(31 檔) | ✅ 5 條(含唯一的 HIGH) | 報告 | ||
| I3 附件上傳下載(14 檔) | ✅ 工具 0 條+首腦補查 1 條 | 報告 | ||
| I4 對外面與插件契約(20 檔) | ✅ 工具 0 條(兩項查證首腦補做) | 報告 | ||
| I5 app 與 domain(40 檔) | ✅ 1 條(Nexus 走明文連線) | 報告 | ||
| I6 持久層(28 檔) | ✅ 工具 0 條+首腦查出六張表零 RLS | 報告 | ||
| 總結 | 19 條歸成 6 張卡,面板首次全勤(84 票零漏投零中斷) | SUMMARY | ||
| 舊 arc(2026-07) | 主專案 BE/FE | Sonar/Semgrep/Trivy | ✅ 已收官(v1.10.1 清理完成) | 索引 |
面板狀態決定可信度,三種「掃完」不一樣:
✅ 面板完整跑完且有實質票數——FR-081 六棒是至今唯一全勤的 arc(84 票全投、零漏投、零中斷)。關鍵不在檔數而在分開跑:六棒一次都沒撞額度,對照 FR-079 B2 撞兩次、跑 14 小時。
⚠️ 工具零發現 ≠ 乾淨——FR-081 的 I3/I4/I6 三棒工具在範圍內都是 0 條,那三棒真正的產出全是首腦補查的(含「六張表零 RLS」)。小範圍的棒次尤其明顯。
⚠️ 下面兩棒要打折看:
S7 等於沒掃——研究員越界跑去重複 S1,middleware/domain service/plugin.py 預設值/login_log/ui_route 從未被讀過。決策者已裁重跑。
R1 的七條可信、「只有七條」不可信——三人驗證面板 105 個 verifier 全部撞額度上限,0 票投出。七條是 runner 與首腦各人工開檔核對兩遍確認的(事實陳述,不是推論),但覆蓋率無法宣稱,故加開 R1b 補掃密碼學核心。
| 卡 | 修什麼 | 嚴重度 |
|---|---|---|
| CM-1575 | 忘記密碼端點外洩重設憑證 | 🔴 CRITICAL |
| CM-1557 | MFA 驗證碼無次數限制 | HIGH |
| CM-1560 | LDAP 三洞(匿名 bind/filter escape/TLS 不驗證) | HIGH |
| CM-1562 | 綁定外部身分無本人檢查 | HIGH |
| CM-1561 | Google 登入殼(裁定:關閉不拔除) | HIGH |
| CM-1576 | 自助 profile 自我提權 | HIGH |
| CM-1572 | 驗章前無界解壓縮(解壓炸彈) | HIGH |
| CM-1579 | 停權可被換照解除 | HIGH(SaaS) |
| CM-1583 | LC 開通端點七項(防猜/計數表/log 遮蔽/補發復活) | HIGH |
| CM-1558 | Turnstile 缺金鑰 fail-open | MEDIUM |
| CM-1563 | 帳號枚舉統一 401 | MEDIUM |
| CM-1564 | LDAP 連線測試改位址強制重輸密碼 | MEDIUM |
| CM-1565 | Redis TLS 不驗憑證 | MEDIUM |
| CM-1573 | jedi-issue PAT 外洩處置 | MEDIUM |
| CM-1577 | update_user 改密碼不驗強度 | MEDIUM |
| CM-1578 | Excel 上傳目錄用未驗證 login_name | MEDIUM |
| CM-1584 | LC 登入 next 開放導轉 | MEDIUM |
| CM-1585 | 角色讀取端點無守門 | MEDIUM 偏 HIGH |
| CM-1586 | 失效角色算成有效 | MEDIUM |
| CM-1587 | 全站請求 body 上限(裁 50MB) | MEDIUM |
| CM-1588 | 租戶/部門部分更新清空上層歸屬 | MEDIUM |
| CM-1589 | 部門/租戶/使用者讀端點補 .read 守門 |
MEDIUM |
| CM-1580 | 跨租戶重複用照部分唯一索引 | LOW |
| CM-1581 | build 公鑰守門路徑 bug | 小 fix |
⚠️ 這 24 張多半只進了 DEV/套件源碼,還沒發版上 STG/POC——見 §5 上版待辦。
按嚴重度排序。全部未動是決策者裁定「PM 收集完所有掃描結果再統一安排」的結果,不是漏派。
| 卡 | 修什麼 | 嚴重度 | 來源 |
|---|---|---|---|
| CM-1595 | Agent 控制面四端點不驗身分(register/heartbeat/ack/result)。免登入即可自報 agent_uid 取走該租戶掃描工具明文憑證(SonarQube token/SSH/WinRM 帳密);跨租戶亦可;ack/result 可偽造或抹除稽核證據。宣稱倚賴的 nginx mTLS 出貨設定裡不存在 | 🔴 CRITICAL | FR-077 R1 F1+F2+F3+F5 |
| CM-1605 | 測試信端點把平台 SMTP 密碼送到呼叫端指定的主機。子租戶管理員可拿走營運方郵件帳密,之後用貴公司名義寄信且通過 SPF | 🟠 HIGH | FR-078 N2 F1(+F5 Discord SSRF 併入) |
| CM-1597 | enroll token 永久有效+可重註冊接管同租戶任一台 agent(依賴 1595,序列做) | MEDIUM | FR-077 R1 F6 |
| CM-1596 | 健康檢查端點 SSRF(可當內網掃描器,需租戶管理員) | MEDIUM | FR-077 R1 F4 |
| CM-1606 | SMTP adapter 兩洞:密碼原樣寫進 log + starttls 不驗憑證 | MEDIUM×2 | FR-078 N1 |
| CM-1607 | 清版控內殘留的已撤銷金鑰(conversation-history 13 檔+Trivy 報告 2 檔+FR-079 F12 的 JWT 金鑰 31 檔);並評估 CI 加秘密掃描 | 衛生 | FR-078+FR-079 |
| CM-1608 | 拔掉腳本硬編的 POC DB 密碼與 blsadmin 密碼。決策者裁測試機專用、密碼不需更換,只做程式碼衛生(os.getenv(..., "<真密碼>") 這個 pattern 本身錯誤) |
衛生 | FR-078 N2 F4/F8 |
| CM-1598 | jedi-common/.env 受版控(目前值無真密碼,風險是結構性的) |
LOW | FR-077 R1 F7 |
| CM-1629 | DB 管理員密碼(與 Redis 同一組)被寫進 249 個檔,其中一份把主機/帳號/密碼湊在相鄰兩行,可直接使用。該帳號 BYPASSRLS,且同一把用在 DEV、出貨基線庫與 STG/POC(POC 依規定等同正式環境) | 🟠 HIGH | FR-081 I2 |
| CM-1630 | 意見回饋六個功能只有「匯出」檢查權限,其餘五個任何登入者都能用;改/刪從不檢查那筆是不是你的,稽核紀錄還把他記成合法操作人。唯一「普通員工現在就能用」的一條 | MEDIUM | FR-081 I2 |
| CM-1631 | Google 雲端硬碟應用程式密鑰與加密金鑰外洩(22 檔)。這把不是每套安裝各自產生的,是 Google 後台一組、所有環境共用——外洩比 JWT 金鑰那條更實在 | MEDIUM | FR-081 I2 |
| CM-1632 | 連 GitHub 兩處 verify=False——帶著存取權杖走不驗憑證的 TLS(本專案同款病第四處) |
MEDIUM | FR-081 I1 |
| CM-1634 | Nexus 私有套件庫走明文連線且是主要來源(26 個專案全一樣)。內網有心人可在安裝時掉包,而打包機產出的是客戶拿到的安裝檔——供應鏈的根 | MEDIUM | FR-081 I5 |
| CM-1633 | 刪除附件安全檢查只做一半(算了過濾結果卻沒用)。目前打不到,未來做批次刪除會靜默刪錯檔 | LOW | FR-081 I3 |
| CM-1559 | RLS fail-open(session_scope 無 user context 時預設 super admin)。影響面最廣,盤點已完整回寫 Notion 卡,等決策者裁修法方向 |
MEDIUM(優先級可降,見下) | FR-075 S2 首腦加開 |
CM-1559 的關鍵更新:盤點發現 X-Tenant-ID: 0 這條利用路徑已被 FR-069.16 擋死(context.py 加了隸屬檢查)。根因仍在,但已不是可利用的漏洞,故優先級可降。runner 建議下刀順序是「先拿掉 not tenant_id 條件(爆炸面只有 signed_token 一條路徑),再改 elif is_pg 為 fail-closed(動全站 session 進入點)」。
| 卡 | 內容 | 綁什麼條件 |
|---|---|---|
| CM-1582 | 客戶包公鑰白名單(出包按環境只編 PROD 鑰,DEV 鑰不進客戶包) | 綁正式 LC 建立 |
這一段最容易漏——它們散在各報告的「建議開卡」段落裡,沒有進 Notion。
| # | 內容 | 嚴重度 | 出處 |
|---|---|---|---|
| 1 | 公告授權補強四合一:AI 儀表板旁路可讀全租戶公告(含草稿,且前三筆原文送第三方 LLM)/改刪公告不驗歸屬且靜默清空發送對象/單筆讀取零檢查/列表對無部門帳號直接全放行 | MEDIUM×2+LOW×2 | FR-079 B2 F13/F16/F17/F18 |
| 2 | 憑證輪替與清除:cmmgr DB 密碼(BYPASSRLS)/四家 LLM API 金鑰(9 檔)/Nexus+MinIO 憑證(供應鏈的根)/migration 腳本把真密碼當環境變數 default |
MEDIUM×4 | FR-079 B2 F1/F2/F3/F14 |
| 3 | installer 每套部署種同一組原廠 super admin 密碼,bcrypt hash 寫死在 SQL、不強制首次改密 | MEDIUM | FR-079 B2 F15(決策者裁:先記錄,之後看怎麼調整) |
| 4 | bulletin_org_units RLS 未設(走 sql-migration SOP) |
— | FR-079 B2 重點⑩ |
| 5 | 三張表有 RLS policy 但 RLS 沒啟用:compliance.projects/workflow_executions/workflow_templates,且 projects 的 policy 沒有 super admin 分支。現在不會出事(policy 沒生效),哪天有人打開 RLS 會直接壞 |
定時炸彈 | CM-1559 盤點順帶發現 |
| 6 | 三環境硬編公鑰:DEV 私鑰簽的照 POC 也認。決策者已裁「現階段不急,綁正式 LC 一併處理」,但尚未落成卡 | 綁正式 LC | FR-076 L1 |
| 7 | jedi-issue 六張表完全沒有客戶隔離:issues/labels/members 與三張 mapping 表零 RLS 零 policy,連「這是哪個客戶的」欄位都沒有(主專案自建的 feedback_issues 有 4 條 policy,對比鮮明)。比 FR-079 那條更徹底——那張至少有欄位、補規則就好,這六張要補得先改表結構。目前實際影響有限(project_name 寫死 "CM"、全租戶共用一份平台設定),但資料庫層對這六張表沒有任何第二道防線,配合 CM-1630 的「改/刪不驗歸屬」等於無兜底 |
低/設計註記(首腦判) | FR-081 I6(首腦補查,工具零發現;已併入 CM-1630 背景說明,未獨立開卡) |
面板判定「不是資安問題」,但程式碼缺陷是確認過的,值得開一張非資安卡順手修:
| # | 內容 | 位置 |
|---|---|---|
| 7 | PUT /tenant/<uid> 與 PUT /org-unit/<uid> 部分更新會把 parent_id 打成 NULL,留下 parent_id 與 path 互相矛盾的資料列 |
tenant_repo_impl.py:44/org_unit_repo_impl.py:52 |
| 8 | 建部門時 created_user 從未被設定(連續兩行都寫 updated_user),兩個稽核欄位都寫成 NULL |
app/service/org_unit_service.py:74-75 |
| 9 | 套件版 update_bulletin() 檢查錯對象(if not bulletin 應為 if not bulletin_model),查無此筆時對 None 設值直接 500 |
jedi-bulletin bulletin_repo_impl.py:56 |
| 10 | 無登入者時建立公告會崩潰(對 None 取 .uid)——好消息是它「炸」而不是靜默寫 NULL 建立者 |
jedi-bulletin bulletin_service.py:50/62 |
9、10 兩條目前打不到(套件那支 service 沒有任何呼叫者,主專案走自己那支)。
| # | 內容 |
|---|---|
| 11 | S7 重跑(CM-1556)——決策者已裁,尚未執行。重跑要收窄掉 infra/adapter/authenticate_adapter/ 與 user_auth_provider_service.py 避免再度越界重複 S1 |
| 12 | R1b 補掃(CM-1599)——只掃 common/agent_auth/ 10 檔的密碼學核心(簽憑證 ca.py/簽 JWT jwt_util.py),R1 面板全滅時這塊分不出「讀過」還是「沒讀到」 |
content 的儲存型 XSS——需開 FE repo 查渲染方式,FR-079 B2 未查。users 表 RLS——FR-079 B2 未查。docs/、scripts/ 兩棵樹從來不是掃描目標——多條金鑰外洩是密鑰專項順手撈到的,「範圍外」的發現不代表那些地方被檢查過(FR-078 N2 與 FR-081 皆明載)。25 支 jedi- 套件,實質掃過 6 支。 未掃合計約 102 棒、122 小時*(純掃描,不含驗收/開卡/修正)。
| 狀態 | 套件 |
|---|---|
| ✅ 掃完 | jedi-iam(S7 待重跑)、jedi-license-runtime、jedi-notification、jedi-bulletin、jedi-issue(六棒全勤,2026-09-10) |
| 🔄 部分 | jedi-remote-agent(R1 完成、餘暫停)、jedi-detection(僅 agent 相關 11 檔,餘 140 檔未掃) |
| ⚠️ 不算數 | jedi-common——只有第一輪未經面板的半途掃描 |
| ⬜ 完全沒碰 | 其餘 17 支 |
首腦建議的下一批順序(按風險,不是按檔數):
session_scope/@transaction/RLS 注入/error handler 都在這,CM-1559 的根也在這。它出問題等於 25 支全中。jedi-oscal-v2(364 檔)建議獨立 arc:風險形狀不同(XXE/解析炸彈/資源耗盡),混進授權鏈掃描會讓卡片失焦。
feedback/ 底下,用檔名 grep issue 會漏掉。24 張 Done 的修正卡多數只在套件源碼與 DEV,尚未發版:
pyproject.toml pin → 重出 image → 部署 STG → 部署 POC⚠️ 上版行為變化提醒(會直接擋連線,上版前先確認):
掃描本身:
憑證處置(FR-081 帶出,三件都要裁):
其他:
.env.test/JWT 金鑰/DB 密碼),九成來自查資料庫的指令被寫進對話紀錄。不改工作方式,清了還會再長出來。已裁決、不要重問的:POC DB 與 blsadmin 密碼不需更換(測試機專用)/不重寫 git 歷史(.env.test 事件)/修正卡一律不派由 PM 統一安排/FR-079 F12 降衛生類併 CM-1607/F15 先記錄不開卡。
六個 arc 各自的站(本表只做收斂,逐條技術細節在各站):
| Arc | 掃什麼 | 站 |
|---|---|---|
| FR-075 | jedi-iam | FR-075-2609-jedi-package-security-audit/ |
| FR-076 | License 簽發與驗證鏈 | FR-076-2609-license-chain-security-scan/ |
| FR-077 | 遠端 Agent 控制鏈(⏸ 暫停) | FR-077-2609-remote-agent-security-scan/ |
| FR-078 | jedi-notification | FR-078-2609-notification-security-scan/ |
| FR-079 | jedi-bulletin | FR-079-2609-bulletin-security-scan/ |
| FR-081 | jedi-issue | FR-081-2609-issue-tracking-security-scan/ |
| 舊 arc | 主專案 BE/FE(2026-07) | security-scan-2607/ |
其他座標:
| 要什麼 | 去哪 |
|---|---|
| 現況與派工紀律(living) | FR-075/handoff/security-scan-STATE.md |
| 歷程(append-only) | FR-075/handoff/security-scan-LOG.md |
| 首腦手冊(切棒/開卡/驗收/裁決) | .claude/skills/security-scan-lead/SKILL.md |
| 工具用法與失敗紀錄 | FR-075/scan-methodology.md |
| 2026-07 工具掃描原始產物 | `docs/security-reports/2026-07-24 |
| 建卡腳本 | scripts/notion_create_case.py |
母卡:FR-075 CM-1546/FR-076 CM-1566/FR-077 CM-1591/FR-078 CM-1602/FR-079 CM-1609/FR-081 CM-1612。
維護紀律:本表由掃描首腦在每一棒驗收完成時同步更新,與回寫母卡同一個動作(
security-scan-leadskill 第五節第 7 步「回寫四處」與 5.1 節)。不要累積到 arc 結束才補——2026-09-09 建好後隔天就因 FR-081 收口而 stale,而 stale 的總表比沒有更糟。