#!/usr/bin/env node /** * sensitive-paths.json 扩展补丁 — 2026-04-25 * * 目标: 将 ai-delivery-pipeline/ 三区目录纳入敏感路径保护 * - staging/ 防止 Edit/Write 直接写入 (应通过 pipeline 流转) * - quarantine/ 防止恶意隔离样本被读回 (red-team-attacker 攻击 3) * - delivery/ 防止直接覆盖交付区 (绕过验证管道) * * 依据: red-team-attacker 攻击 3 [HIGH 75%] "Quarantine 恶意代码图书馆" * red-team-logic C2 [CRITICAL] "用户编辑 quarantine 导致递归 staging" * * 设计: * - 新增 3 条 regex 规则, 匹配 .claude/ai-delivery-pipeline/{staging,quarantine,delivery}/ * - _version bump: v3.9-s1 → v3.10-s1-delivery-pipeline * * 幂等: 若规则已存在 (按 reason 标识) 则跳过。 * 原子: tmp + rename。 * 回滚: .bak 保留。 * 后续: 补丁完成后需 `node scripts/compile-rules.js` 刷新 rules-compiled.json。 */ 'use strict'; const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); const TARGET = path.join(__dirname, '..', '..', 'hooks', 'rules', 'sensitive-paths.json'); const COMPILE_RULES = path.join(__dirname, '..', 'compile-rules.js'); const NEW_RULES = [ { regex: '[\\\\/]\\.claude[\\\\/]ai-delivery-pipeline[\\\\/]staging[\\\\/]', flags: 'i', reason: 'AI 交付流水线 staging 区 (应通过 pipeline 流转, 禁止直写)', }, { regex: '[\\\\/]\\.claude[\\\\/]ai-delivery-pipeline[\\\\/]quarantine[\\\\/]', flags: 'i', reason: 'AI 交付流水线 quarantine 区 (防恶意样本读回 / red-team 攻击 3)', }, { regex: '[\\\\/]\\.claude[\\\\/]ai-delivery-pipeline[\\\\/]delivery[\\\\/]', flags: 'i', reason: 'AI 交付流水线 delivery 区 (禁绕过验证管道直覆盖)', }, ]; const NEW_VERSION = 'v3.10-s1-delivery-pipeline'; function main() { if (!fs.existsSync(TARGET)) { console.error('[patch-spaths] 目标不存在:', TARGET); process.exit(1); } const raw = fs.readFileSync(TARGET, 'utf8'); const json = JSON.parse(raw); const existingReasons = new Set(json.patterns.map(p => p.reason)); const toAdd = NEW_RULES.filter(r => !existingReasons.has(r.reason)); if (toAdd.length === 0) { console.log('[patch-spaths] 规则已存在, 跳过'); process.exit(0); } // 备份 const bakPath = TARGET + '.bak.delivery-pipeline.' + new Date().toISOString().replace(/[:.]/g, '-'); fs.writeFileSync(bakPath, raw, 'utf8'); json._version = NEW_VERSION; json.patterns.push(...toAdd); // 原子写 const newRaw = JSON.stringify(json, null, 2) + '\n'; const tmp = TARGET + '.tmp.' + process.pid; fs.writeFileSync(tmp, newRaw, 'utf8'); fs.renameSync(tmp, TARGET); console.log('[patch-spaths] 追加', toAdd.length, '条规则:'); toAdd.forEach(r => console.log(' +', r.reason)); console.log('[patch-spaths] _version →', NEW_VERSION); console.log('[patch-spaths] 备份:', path.basename(bakPath)); // 刷新编译规则缓存 if (fs.existsSync(COMPILE_RULES)) { try { const out = execSync('node "' + COMPILE_RULES + '"', { encoding: 'utf8' }); console.log('[patch-spaths] rules-compiled.json 已刷新'); if (out.trim()) console.log(out.trim().split('\n').slice(-3).join('\n')); } catch (e) { console.error('[patch-spaths] compile-rules 失败:', e.message); } } } main();