FR-101 · 需求索引 · 本頁由 build 掃資料夾生成
✅ 三棒掃完並驗收收尾(2026-09-16);發現已全數處理(2026-10-01 同步)——淨新增 3 條(匯出公式注入、無部門送回饋被擋、全站成員名冊入口):2 條已修、1 條死程式已刪除(均隨 1.21.0 出貨);FR-081 四張舊卡回歸確認當時一張都沒修,現已全數處理(三件已修、版控殘留已清)。工具重掃同一批檔結論與 FR-081 高度一致但 CM-1633 兩次都沒報。
這是資安掃描系列的一個 arc。 跨 arc 的結論、修正卡狀態、還沒開卡的待辦與覆蓋率,在跨 arc 總表:
security-scan-consolidated/。本頁只講這一支。
三棒全部掃完。J1/J2 已驗收,J3 等驗收。三棒合計淨新增 2 條(J1 一條、J2 一條),J3 零新增。
J1 找到 4 條發現、全部中等、無高風險:兩條是 CM-1630 搬家後的新落點(誰都能改刪別人的回饋、誰都讀得到全部回饋),一條是 CM-1632 的重複(GitHub 連線關掉憑證驗證),淨新增只有 1 條——匯出檔的 Excel 公式注入。另有 1 條工具沒報、人工查出的:任何登入者都拿得到全站使用者名冊(成員清單端點,根因歸總表第 7 項)。詳見 J1 報告。
J2 的結果形狀完全不同:掃描工具在指定的 37 個檔裡一條都沒報,它報的 4 條全部越界到 J1/J3 的檔案,而且就是 J1 已報過驗收過的同 4 條(檔名行號都一樣),淨新增為零。真正的產出來自人工查證卡片六個重點:查出 1 條新缺口——沒有被分配部門的使用者送不出意見回饋,且畫面看不出原因(資料庫隔離規則與欄位可為空的組合,三個檔交叉比對才看得出來);另判定總表第 7 項對 labels 表是誤判——標籤是全站共用的選項字典(碼表),整張表沒有任何「這筆屬於誰」的欄位,回全表是正確行為。這 37 個檔不能算「掃過且乾淨」,詳見 J2 報告。
J3 的價值不在找到新東西,而在確認了兩件事。第一,FR-081 的舊結論一條都沒被修掉——GitHub 連線關掉憑證驗證的兩處(CM-1632)還在、刪除附件守門只做一半(CM-1633)一行未改、意見回饋不驗權限(CM-1630)照舊、版控歷史的舊密碼(CM-1607)仍可撈出。第二,同一批檔重掃會給出幾乎逐字相同的結論——這對工具穩定性是好消息,但也意味著重掃挖不出新東西:CM-1633 那個「算了過濾結果卻只用一半」的錯誤擺在那裡,工具第二次一樣沒報(檢查員的推論停在「現在打得到嗎」,答案是打不到所以判定不成立)。淨新增 0 條,工具報的 5 條裡 4 條越界到 J1,詳見 J3 報告。
意見回饋功能(使用者回報問題、可轉成 GitLab/GitHub 問題單、可夾附件)原本一半在主專案、一半在套件。FR-099 把主專案那一半整組搬進套件 jedi-issue,主專案刪掉五個目錄。搬完後套件的樣子變了,FR-081 在 2026-09-10 掃的是搬家前的版本。
| 變動 | 檔數 | 內容 |
|---|---|---|
| 新增 | 38 | 意見回饋四層+7 條對外 route、守門殼、route 表、插件骨架五檔、4 支隨包 migration |
| 刪除 | 18 | 舊 plugin.py、頂層 ports/ 目錄(併進 domain/ports.py) |
| 既有檔有改 | 25 | GitLab/GitHub 整合、附件、成員那批。邏輯改動約 120 行,其中 GitHub 附件那支刪 34 行改 15 行 |
| 沒動 | 57 | 整合底層與成員、附件的多數檔——沿用 FR-081 結論,不重掃 |
主專案那側整個變形:FR-081 I2 掃的 31 檔宿主接線(api/feedback/、app/feedback/ 等五個目錄)已全部刪除,只剩 core/plugins/issue.py 一支接線檔。當年 I2 那 5 條發現(含唯一一條次嚴重的 CM-1630)現在的落點在套件裡。
feedback_route.py 七條 route 仍只有匯出掛能力點;feedback_service.py 的修改與刪除用 uid 撈出就改就刪,呼叫者帳號只拿去寫審計欄位與關單紀錄,沒有比對是不是本人。verify=False 兩處仍在(infra/github.py:22、github_issue_adapter.py:40)。feedback_issues 開了 RLS(4 條規則、不強制),但它關聯的 issues/labels/三張 mapping 沒有——門上了鎖、牆是空的。_assert_api_wiring 只驗登入與能力點兩項必填;10 顆能力點有 6 顆自陳後端不守(與 FR-098 第 80 項同一種產品決策題)。002 用 SET LOCAL app.is_super_admin='t' 寫 ui_routes。| 棒 | 卡 | 範圍 | 檔數 | 狀態 | 首腦驗收 |
|---|---|---|---|---|---|
| J1 | CM-1826 | 意見回饋全鏈(app/domain/infra)+ api/ 整層 |
31 | ✅ 已掃完(報告):4 條發現全中等,淨新增 1 條;驗證章 verified、12 票全投 |
✅ 已驗(2026-09-16):四條屬實無改判;F1/F2 併 CM-1630(位置更新)、F3 併 CM-1632(越界屬 J3)、F4 新登記總表第 82 項;runner 補查的成員名冊端點屬實歸第 7 項;交付四件齊全(第十二次做滿) |
| J2 | CM-1827 | plugin/、domain/ports.py、common/、標籤三層、4 支 SQL |
37 | ⚠️ 已掃完(報告):工具範圍內 0 條,4 條全越界重複 J1;驗證章 verified、12 票全投、2h33m;六個重點全靠 runner 人工+DEV 實查 |
✅ 已驗(2026-09-16):四條越界判定正確不另計;N1 新登記總表 §3.2 第 18 項(首腦 DEV 重查三項事實全對);第 7 項對 labels 剔除(碼表判斷正確);①與第 80 項同款產品決策題入 §7 第 16 項;交付四件齊全(第十三次做滿) |
| J3 | CM-1828 | 有改動的 25 支整合/附件/成員檔(回歸) | 25 | ✅ 已掃完(報告):淨新增 0;18 票全投、4 通過皆中等(1 範圍內=CM-1632、3 越界重複 J1)、1 條退件(歷史檔);七個重點工具碰兩個、其餘人工 | ✅ 已驗(2026-09-16):回歸確認四張舊卡一張沒修(CM-1632 兩處/CM-1630/CM-1633 一行未改/CM-1607);重掃結論與 FR-081 高度一致;GitLab 側無同款;附件靜默跳過入 §7 待裁;交付四件齊全(第十四次做滿)。FR-101 三棒收尾 |
一次只派一棒,每棒獨立驗收完才派下一棒。掃描版本基準:jedi 套件 repo 4c208d4(branch feature/review);J3 掃的是 3cc966f,兩者之間 jedi-issue 零差異(中間的 commit 只動 jedi-iam)。
⚠️ 主專案接線 core/plugins/issue.py+2 支小檔不在本案,併進之後「日誌+資產+議題三支套件的主專案接線」那棒(BE repo,約 21 檔),等三棒跑完再開卡。
結論:四條全屬實、無改判;淨新增一條中等(第 82 項,匯出公式注入)。CM-1630 與 CM-1632 搬家沒修,位置更新。
| 項目 | 結果 |
|---|---|
| 驗證章狀態 | verified,無拒收原因 |
| 候選 → 去重後 | 4 → 4 |
| 投票 | 12(4 × 3),四條全 3:0;F1 面板由高降中 |
| 未審/中斷 | 0/0 |
| 研究員派出/回收 | 1/1 |
| 耗時 | 3,302 秒(55 分) |
| 掃描版本 | jedi 4c208d4,branch feature/review,工作區乾淨 |
| 範圍 | 31 檔,與工單逐檔對上 |
| # | 白話 | 首腦判定 |
|---|---|---|
| F1 | 任何登入者能改掉/刪掉別人的回饋 | 屬實。feedback_service.py:240/:279 用 uid 撈出就改就刪,呼叫者帳號只寫審計欄位。併 CM-1630,位置更新 |
| F2 | 清單/明細誰都讀得到全租戶 | 屬實。同屬 CM-1630 |
| F3 | GitHub 連線 verify=False |
屬實。重複 CM-1632,檔案屬 J3 範圍(越界) |
| F4 | 匯出 Excel/CSV 公式注入 | 屬實,新登記第 82 項(中)。首腦開檔:export_rows 六欄裡標題/描述/標籤名/建立者暱稱四欄使用者可控,html_to_text 只拔標籤不處理開頭等號;:389 ws.append 與 :378 writer.writerow 直接寫。與第 78 項同病,建議共用一支中和函式 |
issue_member_route.py 只驗登入,member_repostiory.py:23 query(Members).all(),members 表無租戶欄、RLS 關(首腦 DEV 唯讀重查 15:50:0 筆;model 含 email 欄)。屬實,歸總表第 7 項;建議 CM-1630 描述補上這條(原卡只講六個回饋操作)。_attach_issues 先撈受隔離的 feedback_issues 再比對 issues,方向上不會多出別租戶回饋;但 issues 表無租戶欄(DEV 28 筆)、零隔離,「門鎖了牆是空的」。歸第 7 項,不另計。runner 的判斷正確。v-html 所以不成立。| 項目 | 狀況 |
|---|---|
| 報告 | ✅ runner 自行交付 scan-J1-feedback-chain.md |
| commit | ✅ runner 自行 commit(cad9d94b) |
| Notion 回寫+狀態 | ✅ runner 自行完成 |
| 修正卡 | ✅ 已修(CM-2055,1.21.0 出貨;與第 78 項合修) |
✅ 交付四件齊全——本計畫第十二次做滿。
結論:工具對這 37 個檔零產出——報的四條全越界、與 J1 那四條連行號都一樣,判定正確不另計。真正的產出是 runner 人工六個重點:查出一條真 bug(§3.2 第 18 項)、更正一條總表誤判(第 7 項剔除標籤表)。
| 項目 | 結果 |
|---|---|
| 驗證章狀態 | verified |
| 候選 → 去重後 | 4 → 4,四條的檔案都不在 37 檔 scope 內(首腦逐檔比對) |
| 投票 | 12 全投、全 3:0 |
| 耗時 | 9,175 秒(2 小時 33 分);第一位研究員被砍掉重派 |
| 掃描版本 | jedi 589d034(該 commit 只動 jedi-iam,J2 範圍與 4c208d4 零差異) |
feedback_issues_insert policy 原文為 app_tenant_allowed_for_session(tenant_id) AND (can_read_all_orgs OR app_org_allowed_for_session(org_unit_id)),無超管旁路(另三條有);app_org_allowed_for_session(NULL) 回 f;users 中 org_unit_id IS NULL 且非超管的帳號 1 個。三件事合起來=沒部門的人送回饋必被擋且無錯誤訊息。登記 §3.2 第 18 項,修法三選一入 §7 第 17 項待裁。labels:七欄(id/uid/name/color/description/scope/is_deleted),無租戶、部門、建立者欄;內容 FUNCTION 16 筆、FEEDBACK_TYPE 3 筆等下拉選項。依 §5「有沒有主人」判準回全表正確。總表第 7 項由六張改五張(issues/members/三張 mapping 仍零隔離)。system_core.py:69 對照表真擋整合設定四顆,回饋五顆只前端認。與第 80 項同一種產品決策題,入 §7 第 16 項,建議與第 80 項一起裁。其餘:守門殼正面案例(缺必填拒絕掛載)、SET LOCAL 在 --single-transaction 內安全、四支 migration 冪等、錯誤碼乾淨、整合金鑰套件內不落 log——首腦抽核 ②④ 兩項屬實,其餘採信。
| 項目 | 狀況 |
|---|---|
| 報告 | ✅ runner 自行交付 scan-J2-plugin-label-migration.md |
| commit | ✅ runner 自行 commit(22bb4dba) |
| Notion 回寫+狀態 | ✅ runner 自行完成,含四題待裁(現均已裁) |
| 修正卡 | ✅ 已處理(見 security-report M21 問題表;1.21.0 出貨) |
✅ 交付四件齊全——本計畫第十三次做滿。
結論:淨新增 0。這棒的價值不在找新洞,在兩件事——回歸確認 FR-081 四張舊卡一張都沒修,以及證明工具重掃同一批檔會給出幾乎相同的結論。
| 項目 | 結果 |
|---|---|
| 驗證章狀態 | unverified,reason_kind: findings-refused(F5 的 .env 在 git 歷史、不在樹裡,被渲染器退件)——面板完整跑完、18 票全投,第三種型態不算失敗 |
| 候選 → 去重後 | 6 → 6;通過 4 皆中等、退件 1、駁回 1 |
| 研究員 | 2 派 2 回 |
| 耗時 | 8,093 秒(2 小時 15 分) |
| 掃描版本 | jedi 3cc966f8;掃描期間平行線 commit 651e33c(jedi-file-upload),首腦確認對 jedi-issue 零差異 |
| 範圍內產出 | 1 條(F1=CM-1632 行號 43→40),其餘 3 條越界到 J1 範圍(首腦逐檔比對) |
local_issue_attachment.py:87 算出過濾後集合、:91 刪對應關係用過濾後的、:98 刪實體檔用回未過濾的 file_uids。與 FR-081 I3 描述一致。工具兩次都沒報——它只問「現在打得到嗎」(單一呼叫點只傳一個編號),程式寫錯這件事它不會說。infra/gitlab.py:27、gitlab_issue_adapter.py:44 的 gitlab.Gitlab( 建構都沒傳 ssl_verify,套件預設驗證。CM-1632 只在 GitHub 這半。github_issue_attachment.py:103-108 只記檔名進 WARNING、回空清單;使用者端無提示。產品決策題入總表 §7。except Exception、本地路徑只用 issue 編號、CM-1807 已修、entity 必填未變選填)抽核 ①④ 屬實,其餘採信。| 項目 | 狀況 |
|---|---|
| 報告 | ✅ runner 自行交付 scan-J3-integration-regression.md |
| commit | ✅ runner 自行 commit(ad70978f) |
| Notion 回寫+狀態 | ✅ runner 自行完成,含三題待裁(現均已裁) |
| 修正卡 | ✅ 已處理(見 security-report M21 問題表;1.21.0 出貨) |
✅ 交付四件齊全——本計畫第十四次做滿。FR-101 三棒收尾。
| 項目 | 變動 |
|---|---|
| §3.1 | 新增第 82 項(J1);第 7 項六張改五張(J2) |
| §3.2 | 新增第 18 項(J2) |
| §7 待裁(現均已處理) | 回饋五顆權限點要不要守(第 16)/無部門送回饋修法(第 17)/附件靜默跳過要不要告知(第 18) |
| 已開卡未修 | CM-1630/1632/1633/1607 位置更新(當時全部未修;09-21 作廢、改照問題總表派工,現已全數處理:三件已修、版控殘留已清) |
| 掃描方法 | 工具對同一批檔重掃結論一致;對骨架、碼表、SQL 類的檔零產出(J2);對「程式寫錯但現在打不到」的錯誤兩次都不報(CM-1633) |
範圍、切法、動機都不同:FR-081 按「攻擊面」切六棒、面板六棒全部投完票,是本專案最乾淨的一批紀錄。續在底下會把「130 檔舊版全掃完」與「151 檔新版只掃變動」混在同一份進度表。FR-081 README 加一段指向本 FR。
57 支內容與 2026-09-10 掃過的版本逐字相同(git diff ed62d8a..HEAD 零差異),工具產物與六份報告仍有效。重掃只多燒一輪面板,換不到新資訊。
25 支邏輯改動只有約 120 行,本可省。掃的理由兩個:GitHub 附件那支是唯一實質行為變更(從「拋例外導致整張 issue 沒建」改成「靜默跳過附件只記 warning」,對不對要驗);以及這是第一次有機會驗「工具對同一批檔重掃,結論一不一致」,成本一棒。
| 項目 | 值 |
|---|---|
| 主 session 模型 | Opus 5 (1M context),不要用 Sonnet |
| effort | low |
| scanRoot | ~/Projects/Jedicogy/module/jedi-python-package/jedi-issue |
| 派工節奏 | 一次只派一棒,驗收完才派下一棒 |
掃完要逐項回頭核工單的「重點看什麼」——快篩模式下工具常只咬住一個最顯眼的攻擊模式(FR-097 L1 最嚴重那條工具完全沒碰、FR-098 A1/A2 五六個重點只碰一個)。工具沒答的自己開檔查了再寫,標「(工具未報,人工查證)」。報告格式抄 FR-098 A2。
.claude/skills/security-scan-lead/SKILL.mddocs/features/security-scan-consolidated/docs/features/FR-081-2609-issue-tracking-security-scan/docs/features/FR-099-2609-feedback-label-into-jedi-issue/~/Projects/Jedicogy/module/jedi-python-package/jedi-issue/feature/review(2026-09-16 開卡時實查)以下全部由 build 掃資料夾產生,新增檔案重 build 即自動出現。標題連結指向渲染後的 HTML,md 連向源檔。
| 文件 | 類型 | 標題 | 最後更新 |
|---|---|---|---|
| scan-J1-feedback-chain / md | 盤點證據 | J1 檢查結果:意見回饋全鏈+對外 route 與守門殼(jedi-issue) | 2026-09-16 |
| scan-J2-plugin-label-migration / md | 盤點證據 | J2 檢查結果:插件骨架+標籤鏈+隨包 migration+共用(jedi-issue) | 2026-09-16 |
| scan-J3-integration-regression / md | 盤點證據 | J3 檢查結果:有改動的整合與附件層(回歸重掃) | 2026-09-16 |