Regression / regression (push) Canceled after 0s
## 品牌标识(本次会话) 起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」, 那是 v2.0.0「Aurora Admin → Kole UI」改名漏掉的一处(PC 顶栏也是「A」, 移动端站已是「K」;移动端文档站则完全没有 favicon)。 - 几何:24 网格三个互不接触的笔画(竖 + 两斜),圆头描边; 描边 2.25 → 16px 标签页尺寸下正好 1.5px = 规范原文「描边1.5px」 - 取色分两套(刻意):favicon 硬编码品牌蓝/白(渲染在浏览器标签栏,不继承 kole-dark); 顶栏标记走 currentColor(实测暗色下自动转 rgb(20,22,28)) - 新增 theme-color 双条(light #FFFFFF / dark #1C1F26,取 --kole-color-card-bg) - 修 site/app.js hero 标语 KOLE ADMIN → KOLE UI(改名变形残留) - 移动端 7 个模板补 favicon(此前计数 0) 验收:门禁 9 条全 OK(site-routing/site-routes/mobile-docs/mobile-site/isolation/ theme/nav/i18n/icons);PC 回归 1464/1464 · 移动端 807/807,各连跑 8 次一致; 两端 favicon 405 字节逐字节一致;PC 站控制台错误 1→0。 ## 并行会话成果(本次一并入库) - 图标系统:2576 图标(TDesign/Element Plus,MIT)+ 11 端注入 + 5 个构建门禁工具 + IconPreview 预览页 + ICON-SPEC.md 冻结规格 - 移动端平台:47 组件 × 6 端 + 文档站 53 页 + 隔离门禁 - PC 组件:103 个大后台组件 / 组件11 批次 - uni-app:PC 端试点 + 移动端端实现 + 真实编译验证 ## 工程 - .gitignore 补 .scratch/ 与 .zcode-preexisting-*.txt(会话中间产物,实测 9.1MB,不入库) - CHANGELOG 补品牌标识条目 - ROADMAP 登 S8-P4(品牌标识任务包 + og:image/apple-touch-icon 未做部分)
297 lines
21 KiB
Markdown
297 lines
21 KiB
Markdown
# 安全审计修复说明与待决事项
|
||
|
||
> 生成时间:2026-09-19 | 审计对象:本仓库 + `192.168.5.7` 上运行的 `kole-ui-showcase` 容器
|
||
> 本文档分两部分:**已修复**(我直接做了,含证据)与 **待你拍板**(我做不了主的,逐项给选项与建议)。
|
||
|
||
---
|
||
|
||
## 一页速览
|
||
|
||
| 状态 | 数量 | 说明 |
|
||
|---|---|---|
|
||
| 已在仓库修复并验证 | 6 项 | 见第二节,全部有 exit 0 证据 |
|
||
| **已部署并在线上验收** | 全部 | 2026-09-19 重建容器:6/6 断言 + 396/396 URL + 响应头全项通过,见第三节 |
|
||
| 仍待你拍板 | 4 项 | D3 / D4 / D6 / D8(D1、D2、D5、D7、D9、D10 已决,见第四节开头) |
|
||
| 过程异常 | 4 项 | 见第五节 E1–E4(你已确认无其它会话,属当时并发写入) |
|
||
|
||
**一句话**:洞已堵上且已上线——线上访问 `specs/组件1.txt` 现在返回 404,站点 396 条 URL 全部 200。
|
||
|
||
---
|
||
|
||
## 二、已修复(仓库层,全部已实测验证)
|
||
|
||
### 1. 规范原文泄漏的根因(`.dockerignore`)
|
||
|
||
**问题**:`.dockerignore` 里 `*.md` / `*.ps1` / `*.yml` / `*.png` 这类写法,在 Docker 下**只匹配构建上下文的根目录**。实测(真实 docker build):
|
||
|
||
```
|
||
.dockerignore: *.md
|
||
COPY . /out/ -> /out/sub/nested.md ← 嵌套文件照样进镜像
|
||
```
|
||
|
||
所以 `.design_library/kole-ui/SKILL.md`、嵌套 `README.md` 等一直会被打进镜像;而部署目录 `/opt/kole-ui` 干脆**没有** `.dockerignore`,于是 `specs/`、`agent-reports/`、`preview/`、`ui_kits/` 全部随 `COPY .design_library/` 进了镜像并对外可下载。
|
||
|
||
**修复**:glob 全部加 `**/` 前缀,保留显式目录排除与 `!README.md`(只放行根级 README)。
|
||
|
||
**验证**(我在服务器上用当前文件做真实构建):
|
||
|
||
```
|
||
应排除 -> specs/ 0 | agent-reports/ 0 | preview/ 0 | ui_kits/ 0 | nested.md 0 | AGENTS.md 0 | docker-compose.yml 0
|
||
应保留 -> site/index.html 1 | site/data.json 1 | site/tokens/tokens.css 1 | site/sources/x.txt 1
|
||
frameworks/*.css/.vue3 1 | tests/index.html 1 | tests/report.json 1
|
||
.design_library/kole-ui/components/button.json 1 | README.md 1
|
||
BUILD_EXIT=0
|
||
```
|
||
|
||
### 2. `nginx.conf` 加固
|
||
|
||
- 补 `absolute_redirect off;` —— 修复根路径 302 丢失宿主端口(`Location: http://192.168.5.7/site/`,而该机 :80 无服务 → 根地址直接打不开)。
|
||
- 补 `server_tokens off;` —— 不再暴露 `nginx/1.31.3`。
|
||
- 补 CSP + `X-Content-Type-Options` + `Referrer-Policy` + `Permissions-Policy` + `X-Frame-Options`,CSP 与 `site/dev-server.js` 里的 `SECURITY_HEADERS` **逐字一致**(本地长期验证可用的组合,避免过严导致演示页白屏)。
|
||
- `/healthz` 改用 `default_type`,消除重复的 `Content-Type`(原先是 `return 200` 的默认类型与 `add_header` 叠加)。
|
||
|
||
**验证**:子 agent 在真容器里跑 `nginx -t` → `syntax is ok` / `test is successful` / `exit 0`;并做了修复前/修复后运行时对照(`Location` 由绝对变相对、`Server` 由 `nginx/1.31.3` 变 `nginx`、`/healthz` 由两条 Content-Type 变一条且不丢安全头、gzip 行为等价)。
|
||
|
||
### 3. `Dockerfile`
|
||
|
||
补 `COPY sitemap.xml /usr/share/nginx/html/sitemap.xml`(此前生产 `/sitemap.xml` → 404)。
|
||
未动基础镜像 tag、未加 `USER`(nginx 官方镜像 master 需 root 绑 80,擅自改会让容器起不来)——运行期加固见 D6。
|
||
|
||
### 4. `site/dev-server.js`:单请求崩溃
|
||
|
||
**问题**:`GET /site/%00` → `decodeURIComponent` 解出 NUL → `fs.readFile` 同步抛 `ERR_INVALID_ARG_VALUE` → 异常逃逸出请求回调 → **整个进程退出**(畸形百分号编码反而处理正确)。CI 与本地回归都跑这个服务。
|
||
|
||
**修复**:编码形态拦截补 `00`/`2500`、解码后**再做一次** NUL 校验(双保险)、`readFile` try/catch。未使用 `uncaughtException` 兜底(那是掩盖)。行为不变:92 条合法路径 status / content-type / 字节级一致。
|
||
|
||
**验证**:`node tools/verify-dev-server.mjs` → **20 checks / EXIT=0**,含 3 条「修复前必失败」的反例断言(进程存活、突发后仍 200、stderr 无崩溃栈)。
|
||
|
||
### 5. 消除动态求值 sink(运行期 + 构建期)
|
||
|
||
**问题**:`site/app.js` 与 `tools/precompute.mjs` 都把 `defineEmits([...])` 的数组字面量交给函数构造器求值。实测:
|
||
|
||
```
|
||
输入 defineEmits([1, globalThis.__pwned = "executed-arbitrary-js"])
|
||
旧实现 -> 真的执行了
|
||
```
|
||
|
||
即:任何能改 `frameworks/*.vue*` 的人(投毒 PR / 内部威胁)在组件详情页被打开时即可执行同源 JS;构建期同源版本**在构建机上执行**,而 CI 往往带 secrets。
|
||
|
||
**修复**:改成只解析字符串字面量的 `parseStringLiteralArray`——非字符串元素 / 未识别转义 / 裸换行 / 结构不符一律整体拒绝返回 `null`(跳过抽取、不报错、绝不执行)。构建期实现独立成 `tools/lib/parse-string-literal-array.mjs`。
|
||
|
||
**等价性验证**:`node tools/verify-emits-parse.mjs` → **17 checks / EXIT=0**,158 个 `frameworks/*.vue` 双实现抽取结果**不一致 0**(54 处字面量 / 96 条事件名),且新实现对 6 类对抗输入全部拒绝、不执行。
|
||
|
||
### 6. 新增验证脚本与变更记录
|
||
|
||
- `tools/verify-dev-server.mjs`(20 checks)、`tools/verify-emits-parse.mjs`(17 checks)——均为零依赖、`exit 1` 表示失败、含「修复前会失败」的反例断言。
|
||
- `CHANGELOG.md` 追加 `[Unreleased] → Security · 生产部署链审计修复(2026-09-19)`。
|
||
- ⚠️ **规划修正**已在 CHANGELOG 标注:`PLAN.md` §8「不改 `site/dev-server.js`(已工作良好)」的立论被实测推翻,按 AGENTS.md 第五节「以实测为准」处理。
|
||
|
||
### 回归证据
|
||
|
||
```
|
||
连跑 9 次(子 agent):每次 passRate 100% | pages 79 (all-pass 79) | 1017/1017 | N/A 34 | rc=0
|
||
主 agent 独立复跑 1 次(独立端口 13411):passRate 100% | 1017/1017 | N/A 34 | EXIT=0
|
||
零依赖铁律:zero-dep OK(EXIT=0)
|
||
```
|
||
|
||
---
|
||
|
||
## 三、已部署(2026-09-19)
|
||
|
||
按 AGENTS §九 的标准流程部署(备份 → 暂存目录核对 → 替换 → `docker compose build && up -d`)。共执行两次:
|
||
1. **修复落地**:把审计修复 + 工作树当前状态推上线(消除 288 文件漂移)。
|
||
2. **重新部署**:`npm run build:site` 两步构建重生成 `data.js` / `data.json` / `site/sources` / `site/details` 后,再跑一次打包流程保持线上与仓库一致(实测线上 `/site/data.js` 102,555B、`/site/data.json` 1,251,099B,与仓库一致;`data.json` 仍为完整版,符合铁律 5)。
|
||
|
||
回滚点:
|
||
- `/opt/kole-ui.pre-audit-20260919-0609` —— 审计前的原始状态(含被泄漏的 `specs/`、旧 `nginx.conf.bak`)
|
||
- `/opt/kole-ui.prev-20260919-0614` —— 第一次修复部署后的状态
|
||
- `/root/kole-ui-backup-20260919-0609.tgz`(877 KB)、`/root/kole-ui-backup-20260919-0614.tgz`(882 KB)
|
||
|
||
| 项目 | 修复前(实测) | 修复后(实测) |
|
||
|---|---|---|
|
||
| `/.design_library/kole-ui/specs/组件1.txt` | **200 / 8623B**(规范原文可下载) | **404** |
|
||
| `/.design_library/kole-ui/agent-reports/*.json` | 200 | **404** |
|
||
| 嵌套 `SKILL.md` / `README.md` | 200 | **404** |
|
||
| `/AGENTS.md`、`/package.json`、`/Dockerfile`、`/nginx.conf` | 404 | 404(一直未泄漏) |
|
||
| `/sitemap.xml` | 404 | **200** |
|
||
| `tests/report.json`(首页通过率角标数据源) | 404 | **200** |
|
||
| 根路径 302 | `Location: http://192.168.5.7/site/`(丢端口,落点无服务) | **`Location: /site/`**(相对,保留端口) |
|
||
| 响应头 | 无安全头,`Server: nginx/1.31.3` | CSP + `nosniff` + `Referrer-Policy` + `Permissions-Policy` + `X-Frame-Options`,`Server: nginx` |
|
||
| `/healthz` | 两条 `Content-Type` | **1 条**,且安全头未丢 |
|
||
| `/site/dev-server.js` | 旧版(无白名单/无敏感路径过滤) | 加固版(`isPublicPath` + `KOLE_PORT`) |
|
||
| 组件文件 | 09-06 快照,与仓库漂移 288 个文件 | 与工作树一致 |
|
||
| sitemap 的 396 条 URL | 396/396 → 200 | **396/396 → 200**(无回归) |
|
||
| 容器 | healthy | healthy |
|
||
|
||
对 Agent 承诺的资源(`.design_library/kole-ui/{metadata.json,components/index.json,css.json,colors_and_type.css}`)仍正常 200 —— 排除的只是规范原文、agent-reports、preview、ui_kits 这些不该外发的部分。
|
||
|
||
**访问方式**:按你的决定保持 `127.0.0.1:3311` 回环。经实测确认,服务器上**没有任何 frp 隧道 / 反代 / 域名指向该服务**,所以从任何其它机器都打不开是必然的——唯一的访问路径是 SSH 隧道:
|
||
|
||
```bash
|
||
ssh -o ExitOnForwardFailure=yes -N -L 13311:127.0.0.1:3311 root@192.168.5.7
|
||
# 浏览器打开 http://127.0.0.1:13311/site/ (本机 13311 是为了不占本地 dev-server 的 3311)
|
||
```
|
||
|
||
已实测:经隧道对线上部署跑完整文档站冒烟(真实浏览器)全部通过——路由、中英切换、主题面板、详情页渲染均正常。
|
||
若想让**局域网内其它设备**也能直接打开 `http://192.168.5.7:3311/`,需把 compose 绑定改为 `0.0.0.0:3311` 并注意 Docker 会绕过 ufw —— 这属于显式暴露变更,等你说一句我就改。
|
||
|
||
---
|
||
|
||
## 四、待你拍板(D1–D10)
|
||
|
||
> **2026-09-19 决定记录**(依据你的指示「暂时不考虑线上公用,但是还是得部署,修改原本的设计和计划」):
|
||
>
|
||
> | 项 | 结论 | 落地位置 |
|
||
> |---|---|---|
|
||
> | D1 是否部署 | ✅ **已部署**(按流程:备份 → 暂存核对 → 替换 → 重建;6/6 断言 + 396/396 URL 通过) | 本文第三节、CHANGELOG `Deploy` 段 |
|
||
> | D2 部署方式 | ✅ **已改为可复现**:新增 `tools/pack-deploy.mjs`(`.dockerignore` 为唯一真源 + 硬断言),流程写进 AGENTS §九 | `tools/pack-deploy.mjs`、`AGENTS.md §九`、`ROADMAP S5-P13` |
|
||
> | D5 端口暴露 | ✅ **保持回环**、不对外公用;AGENTS §九 明确「打不开是正常的,用 SSH 隧道」 | `AGENTS.md §九` |
|
||
> | D7 PLAN §8 冻结条款 | ✅ **已按实测修正**(§7 与 §8 两处都标注 ⚠️ 规划修正) | `PLAN.md`、`CHANGELOG.md` |
|
||
> | D9 测试基线口径 | ✅ **已同步**为 1017 通过 / 0 失败 / 34 N/A / 共 1051(标注口径来源) | `TESTING.md`、`AGENTS.md §八`、`ROADMAP 规划修正记录` |
|
||
> | D10 是否还有其它会话 | ✅ **你已确认无**;本次审计中观察到的是当时并行写入,后续已复核无冲突 | 本文第五节 E1–E4 |
|
||
>
|
||
> **仍未决**:D3(`tests/report.json` 是否随镜像发布)、D4(正式域名)、D6(容器运行期加固)、D8(契约对外承诺口径)。这四项已登记为 ROADMAP 任务包 S5-P14/P15/P16,等你有空再定。
|
||
|
||
### D1|是否现在重建并重新部署线上容器?【最高优先】
|
||
|
||
- **选项 A(建议)**:只同步「本次修复的文件集」重建,不动组件文件。范围小、可回滚、立即堵住规范原文泄漏与掉端口问题。
|
||
- **选项 B**:把当前工作树整体同步(顺带消除 288 文件的漂移)。代价:会把仓库里 286 个**未提交**的组件改动一起上线(这些改动本地回归 100%,但等于一次完整发布)。
|
||
- **选项 C**:暂不部署,只保留仓库修复。
|
||
|
||
**我的建议**:先做 A(堵漏),B 作为一次独立「发布」动作、等工作树改动提交审阅后再做。
|
||
|
||
选 A 时的执行序列(等你一句话我就执行):
|
||
|
||
```bash
|
||
# 1) 备份现状(在 192.168.5.7 上)
|
||
cd /opt/kole-ui && tar -czf /root/kole-ui-$(date +%Y%m%d-%H%M).tgz .
|
||
|
||
# 2) 只更新 5 个文件:nginx.conf / Dockerfile / .dockerignore / site/dev-server.js / site/app.js
|
||
# (加上新增的 tools/lib、tools/verify-*.mjs 可选)
|
||
|
||
# 3) 重建并重启
|
||
docker compose build && docker compose up -d
|
||
|
||
# 4) 验收断言(四条必须全中)
|
||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3311/.design_library/kole-ui/specs/组件1.txt # 期望 404
|
||
curl -sI http://127.0.0.1:3311/ | grep -i '^Location' # 期望 /site/
|
||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3311/sitemap.xml # 期望 200
|
||
curl -sI http://127.0.0.1:3311/healthz | grep -ci '^content-type' # 期望 1
|
||
```
|
||
|
||
### D2|部署方式:怎么根治「手工拷贝导致漂移」
|
||
|
||
**这就是这次事故的根因**:`/opt/kole-ui` 是手工拷贝的目录,无 git、无 `.dockerignore`,所以
|
||
① 排除规则失效导致规范泄漏;② 曾经修好的 `absolute_redirect off;` 被下一次拷贝覆盖(它只存在于 `nginx.conf.bak-20260916`,从未进过仓库 git 历史)。
|
||
|
||
- **选项 A(建议)**:改用 rsync/脚本按固定排除清单同步 + 重建,排除清单与 `.dockerignore` 保持同一份真源。
|
||
- **选项 B**:服务器上 `git clone` 仓库 + `docker compose build`,用 git 版本作为唯一真源。
|
||
- **选项 C**:保持现状手工拷贝(不推荐,同样的回退会再来一次)。
|
||
|
||
### D3|`tests/report.json` 要不要随镜像发布
|
||
|
||
- **现状**:当前 `.dockerignore` **保留**它 → 重建后首页「通过率」角标会在线上显示(子 agent 一度排除,被我方流程外的改动改回保留,并在文件里写了理由)。
|
||
- **选项 A(建议)**:保留 —— 首页那个「79 测试页 + 通过率」卡片本来就在页面上,显示数字才算兑现。
|
||
- **选项 B**:排除 —— 镜像更干净,但卡片静默不显示(当前线上就是 404 → 静默隐藏)。
|
||
- 若选 B,删掉 `.dockerignore` 中相关保留注释对应的行即可回滚。
|
||
|
||
### D4|sitemap 与包的正式域名(`SITE_URL_BASE`)
|
||
|
||
`sitemap.xml` 内容目前是 `https://YOUR-ACCOUNT.github.io/kole-ui/…`(占位域名),`package.json` 的 `repository` / `homepage` 同样是占位。
|
||
|
||
- **需要你给**:正式域名(或明确「不做 SEO,接受占位」)。
|
||
- `build-site.ps1` 已支持通过环境变量 `SITE_URL_BASE` 覆盖;`tools/release.mjs` 已有占位符闸门会拦住正式发布。
|
||
- 顺带一提:`tools/verify-site-routing.mjs` 目前**断言 sitemap 里必须含占位 URL**——如果换了真域名,这个断言要同步改(否则校验会失败)。
|
||
|
||
### D5|端口暴露策略
|
||
|
||
- **现状**:绑定 `127.0.0.1:3311`,只有本机/SSH 隧道能访问(我从局域网直连 `192.168.5.7:3311` 超时,符合预期)。
|
||
- **选项 A(建议)**:保持回环,并在 README/交接文档写明「必须隧道访问」,避免有人以为服务挂了。
|
||
- **选项 B**:挂 1Panel 反代 + 域名(要不要加 Basic Auth / IP 白名单?)。
|
||
- 影响面:选 B 会让规范原文泄漏面从「本机」变成「公网」,必须先把 D1 做完。
|
||
|
||
### D6|容器运行期加固(需要一次重启窗口)
|
||
|
||
`read_only: true` + `tmpfs`、`cap_drop: [ALL]`、`security_opt: no-new-privileges`、基础镜像 digest 固定。
|
||
好处明确,但改 compose 后必须重建容器,且 `read_only` 配错会让 nginx 起不来(需要临时可写 `/var/cache/nginx`、`/var/run`)。要不要做、什么时候做,你定。
|
||
|
||
### D7|`PLAN.md` §8 冻结条款的修正
|
||
|
||
`PLAN.md` §8 写着 `❌ 不改 site/dev-server.js(已工作良好)`,§7 有对应验收条目。实测推翻了「已工作良好」,我已按 AGENTS.md 路径修了代码并在 CHANGELOG 标注 ⚠️ 规划修正,但**没有改 `PLAN.md` 本身**(它在冻结清单里)。
|
||
需要你确认:是否把该行改成「dev-server 的畸形路径处理属必修项」。
|
||
|
||
### D8|契约 JSON 的对外承诺怎么统一
|
||
|
||
- **本地**:79 份契约 + `index.json`。
|
||
- **线上**:只有 `button/card/input/modal/select/table.json` + `index.json`(7 个文件),`tag.json`、`calendar.json` 等 → 404。
|
||
- **文档三处互相矛盾**:`site/llms.txt` 写「契约覆盖全部 79 个组件」;`AGENTS.md` 写「契约 JSON 79」;而 `index.json` 自己的 description 写「其中 **6 个核心组件**另含契约 JSON」。
|
||
|
||
**选项**:A 全量发布 79 份(镜像略大,但对 Agent 消费的承诺为真);B 只发布核心 6 份,并把 `llms.txt`/`AGENTS.md` 的表述统一改为「6 份核心契约 + 79 组件索引」;C 保持现状(不推荐,等于承诺失实)。
|
||
|
||
### D9|测试基线数字的口径同步
|
||
|
||
`TESTING.md` 记的是 `1009 / 35`,HEAD 提交信息也写「回归1009-1009」,而当前工作树实测是 **1017 通过 / 34 N/A**。差异来自工作树里已有的未提交改动,不是本次修复造成。建议在合并这批改动后统一同步(我没改 `TESTING.md`,它不在允许清单内)。
|
||
|
||
### D10|是否还有别的会话/自动化在动这个仓库
|
||
|
||
见第五节 E1–E3。**如果有,建议先停掉再合并**,否则两边互相覆盖。这是本次最需要你确认的运维问题。
|
||
|
||
---
|
||
|
||
## 五、必须让你知情的过程异常
|
||
|
||
**E1|`.dockerignore` 在我方子 agent 交付后被第三方进程改写。**
|
||
子 agent A 交付的哈希是 `3b34ffa6`(其中排除了 `tests/report.json`),磁盘现状是 `843cb650`(保留 `report.json` 并写了理由注释)。功能上现状更优(首页通过率卡片能显示),但 A 报告的 47 条断言**不覆盖**现状版本——所以我用当前文件独立重做了真实构建复验(第二节 1,全过)。这也意味着我已无法声称「这个文件的每处改动都来自本次派活」。
|
||
|
||
**E2|`tools/precompute.mjs`(05:56:41)与 `tools/lib/parse-string-literal-array.mjs`(05:56:45)不在任何子 agent 的允许清单内,却被写入了;且 05:56:29 有一次我没派出的构建运行。**
|
||
那次运行重写了 **494 个文件**(`site/sources/**` 395、`site/details/*` 79、`site/data.js`、`site/data.json`、`site/changelog.json`),但 `sitemap.xml` 与 `site/tokens/*` 未变——即只跑了第二步 `node tools/precompute.mjs`,没跑 `build-site.ps1`。
|
||
我复核了内容与后果:
|
||
- `tools/precompute.mjs` 的 `node --check` 通过、`tools/lib/...mjs` 可加载、与 `site/app.js` 在 158 个 `.vue` 上抽取结果一致、对恶意输入不执行;
|
||
- **重建后的 `site/data.js` 哈希 `5fdffe24…` 与构建前、与线上部署三方完全一致** → 这次构建是语义无损的,同时**独立证明了新的安全解析器不改变构建输出**(不依赖我方验证脚本的口径);
|
||
- 漂移比对从我审计时的「288 个文件不同」变为「289」,差额恰好是本次修复的 `site/app.js`,其余无新增漂移。
|
||
**结论**:改动立意是对的(构建期确实有同一个求值 sink,打穿的是构建机而非浏览器),但来源不明、未走派活流程。若这是你的另一个会话在做同一件事,请注意两边会互相覆盖(见 D10)。
|
||
|
||
**E3|共享模块头部引用的 `tools/verify-precompute-emits.mjs` 并不存在。**
|
||
且注释里描述的「源码逐行等价 + 5000 例种子随机等价」比实际存在的检查更强。我已把注释改为描述**真实存在**的门(`tools/verify-emits-parse.mjs`:158 文件结果等价 + 对抗语料),改动后复跑该脚本仍 `17 checks / EXIT=0`。
|
||
若你确实想要那道更强的门(源码等价 + 随机 fuzz),需要另派一个任务实现。
|
||
|
||
**E4|服务器 `/tmp` 残留 `kole-di-final*`(非本次产物)。**
|
||
我清理了自己创建的全部临时目录与 scratch 镜像;这三项来源不明,未删以免干扰可能仍在运行的会话。生产容器 `kole-ui-showcase` 全程未动(`Up 2 days (healthy)`)。
|
||
|
||
---
|
||
|
||
## 六、审计中被验证为「无问题」的部分(免得重复怀疑)
|
||
|
||
| 检查项 | 结果 |
|
||
|---|---|
|
||
| 路径穿越(`../`、`..%2f`、`%2e%2e`、`....//`、反斜杠、`.git/config`) | 全部 403 |
|
||
| 搜索框 XSS(`<img src=x onerror=…>`) | 0 个注入节点、0 次执行 |
|
||
| 路由滥用 | 无效 slug / 越界路径全部回落首页,无异常 |
|
||
| 代码高亮渲染 | 先全量转义再还原 token,无注入 |
|
||
| 硬编码凭据 | 未发现(命中的都是 design-token 变量名) |
|
||
| 零运行时依赖铁律 | 成立(`dependencies` 为空) |
|
||
| sitemap 里的 396 条 URL | 线上 396/396 → 200(静态页无死链;sitemap 文件本身 404 另见第二节 3) |
|
||
| 容器健康 | `healthy`,`/healthz` 200 |
|
||
|
||
---
|
||
|
||
## 附录:本次审计与修复用到的复验命令
|
||
|
||
```bash
|
||
# 全量回归(需先起服务;服务端口可用 KOLE_PORT 覆盖)
|
||
KOLE_PORT=13411 node site/dev-server.js &
|
||
REG_BASE=http://127.0.0.1:13411 node tools/run-regression.mjs
|
||
|
||
# 两处缺陷的定点验证
|
||
node tools/verify-dev-server.mjs # 20 checks,含 3 条反例断言
|
||
node tools/verify-emits-parse.mjs # 17 checks,158 文件双实现等价
|
||
|
||
# 铁律
|
||
node -e "const p=require('./package.json');const d=Object.keys(p.dependencies||{});if(d.length){console.error('FAIL');process.exit(1)}console.log('zero-dep OK')"
|
||
|
||
# 部署配置复验(在 192.168.5.7 上,用一次性容器,不碰生产)
|
||
docker run --rm -v /tmp/<你的>/default.conf:/etc/nginx/conf.d/default.conf:ro nginx:alpine nginx -t
|
||
```
|
||
|
||
证据留档:`C:\Users\12914\Desktop\组件规范第一套\.zcode\deployed-manifest.txt`(线上 1394 文件哈希清单)、`.zcode\drift-check.mjs`(漂移比对脚本)、`.zcode\sitemap-check.txt`(396 条 URL 清单)。
|