Skip to content

fix(skills): 转义 skill-creator eval-viewer 的 </script> XSS(安全审查) - #73

Merged
jinjunnn merged 1 commit into
alphafrom
fix/s12-skill-creator-xss
Jul 4, 2026
Merged

fix(skills): 转义 skill-creator eval-viewer 的 </script> XSS(安全审查)#73
jinjunnn merged 1 commit into
alphafrom
fix/s12-skill-creator-xss

Conversation

@jinjunnn

@jinjunnn jinjunnn commented Jul 4, 2026

Copy link
Copy Markdown
Owner

安全审查修复:vendored skill-creator eval-viewer XSS

自动安全审查在 S12 T7(PR #70)打包的 Anthropic skill-creator 里发现 MEDIUM XSS:
eval-viewer/generate_review.py 把 eval 数据(含模型产出的 output content / prompt,半可信)
json.dumps 后直插进 <script> 标签,并由本地 HTTP server 自动开浏览器渲染 → 数据含 </script>
即突破标签注入脚本(非纯自伤路径:模型输出可被投毒)。

:embed 前转义 </<\/ + U+2028/U+2029(标准 JSON-in-<script> 加固)。

  • 已验证:突破被中和、普通空格不受影响、内容无损、py_compile 通过。
  • 我们分发此文件(extraResources + 安装时复制到用户机),Apache-2.0 允许修改;标注为 alpha
    安全补丁,re-vendor 须重应用。单一注入点(viewer.html 其余读取走 .textContent,安全)。

🤖 Generated with Claude Code

…endored)

安全审查发现:vendored skill-creator(Apache-2.0,PR #70 打包)的 generate_review.py 把
eval 数据(含模型产出的 output content / prompt,半可信)经 json.dumps 直插进 <script> 标签,
再由本地服务器自动开浏览器渲染 → 内容含 `</script>` 即可突破标签注入脚本。

修:embed 前转义 `</`→`<\/` + U+2028/U+2029 行分隔符(标准 JSON-in-script 加固)。已验证突破
被中和、普通空格不受影响、内容无损、py_compile 通过。标注为 alpha 安全补丁(偏离 upstream),
re-vendor 时须重新应用。单一注入点(viewer.html 其余读取走 textContent,安全)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jinjunnn
jinjunnn merged commit f339c8d into alpha Jul 4, 2026
3 checks passed
@jinjunnn
jinjunnn deleted the fix/s12-skill-creator-xss branch July 4, 2026 08:49
jinjunnn pushed a commit that referenced this pull request Jul 4, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jinjunnn pushed a commit that referenced this pull request Jul 4, 2026
- folder:选目录 → 主进程校验 SKILL.md frontmatter(纯函数 parseSkillFrontmatter,
  name 走 SAFE_NAME 防逃逸)→ 逐文件复制入 .alpha/skills(拒 symlink、跳 .git/
  node_modules、10MB/500 文件帽、失败半成品回滚)→ 桥 + receipt(origin=imported)
  → dispose 免重启生效
- git:https-only 白名单(validGitUrl)→ 浅克隆临时目录(60s 超时,GIT_TERMINAL_PROMPT=0)
  → 定位 SKILL.md(根或唯一子目录)→ 走 folder 同管线 → finally 清理临时目录;
  外来内容绝不执行(PR #73 教训)
- npm:并入插件流(persistPlugin 白名单 + 幂等),导入弹窗带插件风险行
- UI:创建 tab 三张导入卡接真;git/npm 输入弹窗(Enter 提交);失败一律行内红字
  (卡区/弹窗内),toast 只报成功(B11)
- 校验层抽纯模块 ext-import-validate.ts + 10 条单测(非法 frontmatter/防逃逸 name/
  URL 白名单)

verify:typecheck + 276 tests + alpha-check 绿;真 IPC 端到端(合法导入入账本
origin=imported + 已安装列表可见;非法 frontmatter「../escape」拒绝;重复导入拒绝;
弹窗内行内错误)。证据 docs/audits/2026-07-04-s13-t6-visual-verify。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jinjunnn pushed a commit that referenced this pull request Jul 4, 2026
- folder:选目录 → 主进程校验 SKILL.md frontmatter(纯函数 parseSkillFrontmatter,
  name 走 SAFE_NAME 防逃逸)→ 逐文件复制入 .alpha/skills(拒 symlink、跳 .git/
  node_modules、10MB/500 文件帽、失败半成品回滚)→ 桥 + receipt(origin=imported)
  → dispose 免重启生效
- git:https-only 白名单(validGitUrl)→ 浅克隆临时目录(60s 超时,GIT_TERMINAL_PROMPT=0)
  → 定位 SKILL.md(根或唯一子目录)→ 走 folder 同管线 → finally 清理临时目录;
  外来内容绝不执行(PR #73 教训)
- npm:并入插件流(persistPlugin 白名单 + 幂等),导入弹窗带插件风险行
- UI:创建 tab 三张导入卡接真;git/npm 输入弹窗(Enter 提交);失败一律行内红字
  (卡区/弹窗内),toast 只报成功(B11)
- 校验层抽纯模块 ext-import-validate.ts + 10 条单测(非法 frontmatter/防逃逸 name/
  URL 白名单)

verify:typecheck + 276 tests + alpha-check 绿;真 IPC 端到端(合法导入入账本
origin=imported + 已安装列表可见;非法 frontmatter「../escape」拒绝;重复导入拒绝;
弹窗内行内错误)。证据 docs/audits/2026-07-04-s13-t6-visual-verify。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jinjunnn added a commit that referenced this pull request Jul 4, 2026
* feat(ui-mac): S13 T4+T5 详情页实时依赖检测 + 更新通道(REQ-019)

T4:进详情页即实时 which 检测 runtimeDep(复用 ext.checkRuntime,per-dep pill:
检测中/✓/✗ 缺失),缺失给安装指引(brew/xcode-select);不再等点「添加」才发现。
缺失分支像素证据如实递延 T8 真机批(PROBE_PATH 硬编码,无法无侵入模拟;IPC 负例
与 ok/checking 分支已实证)。

T5:更新通道 —— receipts.version < catalog.version 的条目:已安装 tab 顶部「有更新」
分组(版本 diff 行内显示)+ 逐条「更新」+「全部更新」;skill = 按钉版覆盖重装,
plugin = 卸旧配置项再写新钉版(persistPlugin 只追加,防旧版残留);MCP = 确认框重装
(persistMcp 为覆盖写,静默重装会丢 {file:} 密钥引用 → 显式重填,不静默丢);
失败行内红字(B11),toast 只报成功。

verify:typecheck + 266 tests + alpha-check 绿;端到端走通(预埋旧版 receipt →
角标/分组 → 更新 → receipt 翻新 → 角标消失,IPC 读回断言);证据
docs/audits/2026-07-04-s13-t4-t5-visual-verify。sprint.md T4/T5 勾选随本 PR。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci: retrigger alpha-ci (PR event missed)

* feat(ui-mac): S13 T6 导入 folder/git/npm 真实现(REQ-019)

- folder:选目录 → 主进程校验 SKILL.md frontmatter(纯函数 parseSkillFrontmatter,
  name 走 SAFE_NAME 防逃逸)→ 逐文件复制入 .alpha/skills(拒 symlink、跳 .git/
  node_modules、10MB/500 文件帽、失败半成品回滚)→ 桥 + receipt(origin=imported)
  → dispose 免重启生效
- git:https-only 白名单(validGitUrl)→ 浅克隆临时目录(60s 超时,GIT_TERMINAL_PROMPT=0)
  → 定位 SKILL.md(根或唯一子目录)→ 走 folder 同管线 → finally 清理临时目录;
  外来内容绝不执行(PR #73 教训)
- npm:并入插件流(persistPlugin 白名单 + 幂等),导入弹窗带插件风险行
- UI:创建 tab 三张导入卡接真;git/npm 输入弹窗(Enter 提交);失败一律行内红字
  (卡区/弹窗内),toast 只报成功(B11)
- 校验层抽纯模块 ext-import-validate.ts + 10 条单测(非法 frontmatter/防逃逸 name/
  URL 白名单)

verify:typecheck + 276 tests + alpha-check 绿;真 IPC 端到端(合法导入入账本
origin=imported + 已安装列表可见;非法 frontmatter「../escape」拒绝;重复导入拒绝;
弹窗内行内错误)。证据 docs/audits/2026-07-04-s13-t6-visual-verify。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: jinjunnn <slmbaovanetti99@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant