progmune-runtime 3.7.62 → 3.7.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.7.63] — 2026-10-10
4
+
5
+ ### No Input Sanitization 触发词收窄(修冤枉第四刀:删 insert/append/write 通用词)
6
+
7
+ **根因**:trigger 里三个「输出系」通用词系统性词撞,从没在真实语料命中过
8
+ 一条 XSS——`insert` 撞 Kysely `insertInto` 数据入库(docmost 补标注
9
+ 30/30 条 FP)、`append` 撞 Python `list.append` 内存数组(Python 盲测
10
+ 45 项目 270 条 FP)、`write` 撞 `writeFileSync` 文件写入(TS 盲测 8 项目
11
+ FP + docmost 告警流 6 条)。
12
+
13
+ - **修复**:trigger 收窄为 `render|display|output|innerHTML|
14
+ dangerouslySetInnerHTML|echo|printf|sprintf|insertAdjacentHTML`——
15
+ DOM sink 用原始调用名显式保留(`el.insertAdjacentHTML(...)` 的提取名
16
+ 就是 `insertAdjacentHTML`),XSS 本意完整保留
17
+ - **逐条归类(R30)**:TS 盲测 LOST 10(8 项目 writeFileSync 族 +
18
+ webshape_F insertInto/insert)、Python 盲测 LOST 45 项目(全部
19
+ list.append)、ADDED 0/0——**无一例外是存储 I/O 词撞,零 XSS sink**
20
+ - **头条数字零影响(如实)**:TS 795 gold 与 Python 729 gold 均不含
21
+ No Input Sanitization 条目(金标全为 protocol/auth/resource 类),
22
+ recall/precision 不变;docmost 告警流 942→865(No Input Sanitization
23
+ 83→6,残留 6 条为 render/output 词族:react-email 服务端渲染×2、
24
+ 函数名 generatePdfRenderToken 撞 render×1、存储驱动 outputFile×3)
25
+ - **A/B 隔离注记**:主路径 violations 扫描间 7↔10 波动为 LLM 语义映射
26
+ 抖动(已知类,见 skyvern CROSS_DOMAIN 记录),与本次改动无因果——
27
+ safeguard 规则不进 violations(§51 证据流与判定分离),同条件 A/B
28
+ 对照主路径一致
29
+ - **回归锁定**:`src/protocol-detector-nis-trigger.test.ts` 5 例
30
+ (insertInto/writeFileSync/list.append 不触发、insertAdjacentHTML 仍
31
+ 触发、render+sanitize 守卫仍抑制);taintpath 160/160;fr-007
32
+ pre5/post0、fr-016 pre7/post0 维持
33
+ - **已知代价(如实记录)**:`document.write` 的提取名是裸 `write`,
34
+ 与文件写入词法不可区分,本刀后不再命中——三语料里 0 条由
35
+ document.write 驱动;浏览器侧 DOM sink 证据通道(marker 化)留待
36
+ R27 方向
37
+
3
38
  ## [3.7.62] — 2026-10-09
4
39
 
5
40
  ### 迁移脚本排除出应用面(修冤枉第三刀:§49.19 补标注后首个数据驱动修复)
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const protocol_detector_1 = require("./protocol-detector");
5
+ /**
6
+ * No Input Sanitization 触发词收窄(修冤枉第四刀,2026-10-09)锁定。
7
+ *
8
+ * 数据:docmost 补标注 30/30 FP(Kysely insertInto)、Python 盲测
9
+ * 270/270 FP(list.append)、TS 盲测 33/33 FP(writeFileSync 族)——
10
+ * 「输出系」通用词系统性词撞,本意是 XSS sink 却从没在真实语料
11
+ * 命中过一条 XSS。收窄后 trigger 只留真实 sink 语义:
12
+ * render/display/output/innerHTML/dangerouslySetInnerHTML/echo/
13
+ * printf/sprintf + 显式 DOM sink 原始名 insertAdjacentHTML。
14
+ *
15
+ * 已知代价:document.write 的提取名是裸 "write",与文件写入不可分,
16
+ * 不再命中(盲测/语料里 0 条由 document.write 驱动,如实记录)。
17
+ */
18
+ const RULE = "No Input Sanitization";
19
+ const has = (vs) => vs.some((v) => v.rule === RULE);
20
+ (0, vitest_1.describe)("No Input Sanitization:触发词收窄(修冤枉第四刀)", () => {
21
+ (0, vitest_1.it)("数据库写入 insertInto 不再触发(docmost 30/30 FP 根因)", () => {
22
+ const vs = (0, protocol_detector_1.detectSafeguardViolations)(["dbOrTx", "executeTakeFirst", "returningAll", "values", "insertInto", "__progmune_input_effect__"], "PageRepo.insertPage", "typescript");
23
+ (0, vitest_1.expect)(has(vs)).toBe(false);
24
+ });
25
+ (0, vitest_1.it)("文件写入 writeFileSync 不再触发(TS 盲测 8 项目 FP 根因)", () => {
26
+ const vs = (0, protocol_detector_1.detectSafeguardViolations)(["writeFileSync", "mkdirSync"], "uploadFile", "typescript");
27
+ (0, vitest_1.expect)(has(vs)).toBe(false);
28
+ });
29
+ (0, vitest_1.it)("Python list.append 不再触发(Python 盲测 45 项目 270 条 FP 根因)", () => {
30
+ const vs = (0, protocol_detector_1.detectSafeguardViolations)(["users", "append", "sessions", "append"], "register", "python");
31
+ (0, vitest_1.expect)(has(vs)).toBe(false);
32
+ });
33
+ (0, vitest_1.it)("真实 DOM sink insertAdjacentHTML 仍触发(XSS 本意保留)", () => {
34
+ const vs = (0, protocol_detector_1.detectSafeguardViolations)(["insertAdjacentHTML"], "renderComment", "typescript");
35
+ (0, vitest_1.expect)(has(vs)).toBe(true);
36
+ });
37
+ (0, vitest_1.it)("真实渲染 sink render 仍触发,带 sanitize 守卫仍抑制", () => {
38
+ const bare = (0, protocol_detector_1.detectSafeguardViolations)(["render"], "renderTemplate", "typescript");
39
+ (0, vitest_1.expect)(has(bare)).toBe(true);
40
+ const guarded = (0, protocol_detector_1.detectSafeguardViolations)(["render", "sanitizeHtml"], "renderTemplate", "typescript");
41
+ (0, vitest_1.expect)(has(guarded)).toBe(false);
42
+ });
43
+ });
@@ -1090,10 +1090,25 @@ const SAFEGUARD_RULES = [
1090
1090
  ],
1091
1091
  },
1092
1092
  // ── Resource: Input sanitization missing ──
1093
+ //
1094
+ // 修冤枉第四刀(2026-10-09,§49.19 补标注数据):trigger 里三个「输出系」
1095
+ // 通用词在真实与合成语料上系统性词撞,全量 FP——
1096
+ // insert:Kysely insertInto 数据入库(docmost 标注 30/30 FP;
1097
+ // 盲测 webshape_F 2/2 FP)
1098
+ // append:Python list.append 内存数组(Python 盲测 270/270 FP)
1099
+ // write: 文件写入 writeFileSync(TS 盲测 33/33 FP)
1100
+ // 本意是 XSS sink(DOM 插入/文档写入),逐条核实无一条真阳性。
1101
+ // 收窄方案:删通用词,DOM sink 用**原始调用名**显式保留
1102
+ // (extractDirectCalls 对属性访问发射 getName() 原样名:
1103
+ // el.insertAdjacentHTML(...) → "insertAdjacentHTML")。
1104
+ // 已知代价(如实记录):document.write 的原始发射名是 "write",
1105
+ // 与文件写入词法不可区分,本刀后不再命中——盲测/语料里 0 条由
1106
+ // document.write 驱动,风险=浏览器侧代码的 XSS sink 词,留待
1107
+ // marker 化证据通道(R27 方向)。
1093
1108
  {
1094
1109
  name: "No Input Sanitization",
1095
1110
  category: "resource",
1096
- trigger: /\b(render|display|write|output|append|insert|innerHTML|dangerouslySetInnerHTML|document\.write|echo|printf|sprintf)\b/i,
1111
+ trigger: /\b(render|display|output|innerHTML|dangerouslySetInnerHTML|echo|printf|sprintf|insertAdjacentHTML)\b/i,
1097
1112
  safeguards: [
1098
1113
  { pattern: /\b(sanitize|escape|encode|html\w*entities|htmlspecialchars|encodeURI|stripTags|purify|DOMPurify|clean|filter\w*html|escape\w*html)\b/i, label: "sanitize" },
1099
1114
  ],
package/dist/sdk.js CHANGED
@@ -20,7 +20,7 @@ const risk_model_1 = require("./risk-model");
20
20
  const protocol_knowledge_1 = require("./protocol-knowledge");
21
21
  const evidence_repository_1 = require("./evidence-repository");
22
22
  /** Runtime version — stable public identifier. Internal layers evolve underneath. */
23
- exports.RUNTIME_VERSION = "3.7.62";
23
+ exports.RUNTIME_VERSION = "3.7.63";
24
24
  function verify(filePath) {
25
25
  const cert = (0, certify_1.certify)(filePath);
26
26
  const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "progmune-runtime",
3
- "version": "3.7.62",
3
+ "version": "3.7.63",
4
4
  "description": "Progmune — AI Trust Decision Engine. Verify AI-generated code before it reaches production. Outputs APPROVED / NEEDS_REVIEW / BLOCKED with evidence.",
5
5
  "files": [
6
6
  "dist/",