安全决策报告

news-briefing

gen-cover.mjs 中存在未声明的 shell 执行和动态代码注入行为(execSync + 字符串模板生成代码),但受控于合法用途(生成封面图片),无恶意指标,判定为可疑阴影功能。

安装决策优先 来源: ClawHub 扫描时间: 2026/4/20
文件 5
IOC 7
越权项 2
发现 3
最直接的威胁证据

为什么得出这个结论

1/4 个维度触发
阻止
声明与实际能力

发现 2 项声明之外的能力或越权行为。

复核
隐藏执行与外联

提取到 7 个一般风险产物,需要结合上下文判断。

通过
攻击链与高危发现

没有形成明确的恶意路径。

通过
依赖与供应链卫生

依赖结构存在,但暂未看到明显高危告警。

风险分是怎么被拉高的

阴影功能:execSync + 动态代码字符串注入 +25

gen-cover.mjs 未声明 shell 执行能力,代码中将模板字符串拼接成 JS 代码并通过 node -e 执行,违反声明-行为一致性原则

无版本锁定的第三方依赖 +10

@napi-rs/canvas 未声明在 requirements 中,且硬编码 node_modules 路径存在供应链脆弱性

execSync 超时未声明 +7

fetch-news.mjs 用 execSync 执行 curl 超时 30s,属 shell:WRITE 行为但 SKILL.md 仅声明 network:READ

最关键的证据

中危 文档欺骗

未声明的 shell 执行和动态代码注入

gen-cover.mjs 声明为封面图生成工具(输出 cover.png),但实际通过 execSync('node -e "..."') 注入包含完整 canvas 绘图逻辑的模板字符串,并写入 /tmp/gen-cover.js 后执行。SKILL.md 完全未提及 shell 执行、execSync 或动态代码生成,属于明确越权的阴影功能。

scripts/gen-cover.mjs:56
将封面生成逻辑改为独立脚本文件,通过 child_process.spawn 调用,删除 execSync('node -e') 模式;在 SKILL.md 声明 filesystem:WRITE 和 shell:WRITE 权限,或使用 allowed-tools 映射替代。
低危 供应链

@napi-rs/canvas 硬编码 node_modules 路径无版本锁定

gen-cover.mjs 第 68 行硬编码了 @napi-rs/canvas 的 node_modules 嵌套路径(含 pnpm 哈希命名),这种路径极易在依赖更新后失效,且无 package.json 记录版本。

scripts/gen-cover.mjs:68
在脚本目录添加 package.json 声明 @napi-rs/canvas 依赖并锁定版本,动态路径改为 require.resolve 或相对路径查找。
低危 权限提升

execSync curl 未在文档中声明为 shell:WRITE

fetch-news.mjs 用 execSync 调用 curl 发送 HTTP 请求,属于 shell:WRITE 行为(对应 allowed-tools 的 Bash 工具),但 SKILL.md 仅声明了 network:READ 能力,未涉及 shell。虽为合法用途(调用外部 API),但超出了声明范围。

scripts/fetch-news.mjs:73
在 SKILL.md 的参数或声明中补充说明使用 curl subprocess 调用 API,或改用 Node.js native fetch() / https 模块消除 shell 依赖。

声明能力 vs 实际能力

文件系统 阻止
声明 NONE
推断 WRITE
gen-cover.mjs:56 writeFileSync + execSync 写入 /tmp/gen-cover.js 并执行
命令执行 阻止
声明 NONE
推断 WRITE
gen-cover.mjs:83 execSync(node -e ...) 执行动态字符串代码;fetch-news.mjs:73 execSync(curl ...)
网络访问 通过
声明 READ
推断 READ
fetch-news.mjs 访问 api.perplexity.ai、api.ppinfra.com;send-card.mjs 访问 open.feishu.cn(均为合法业务API)
浏览器 通过
声明 NONE
推断 NONE
send-card.mjs:84 仅将 Google 搜索 URL 作为 fallback,不实际打开

可疑产物与外联

中危 外部 URL
https://openclaw.ai

SKILL.md:138

中危 外部 URL
https://clawhub.com/u/derekhsu529

SKILL.md:138

中危 外部 URL
https://api.perplexity.ai/chat/completions

scripts/fetch-news.mjs:65

中危 外部 URL
https://api.ppinfra.com/v3/openai/chat/completions

scripts/fetch-news.mjs:122

中危 外部 URL
https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal

scripts/send-card.mjs:35

中危 外部 URL
https://www.google.com/search?q=$

scripts/send-card.mjs:84

中危 外部 URL
https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id

scripts/send-card.mjs:140

依赖与供应链

包名版本来源漏洞备注
@napi-rs/canvas 0.1.95 (硬编码路径) pnpm 无 package.json 锁定版本,硬编码 node_modules 嵌套路径

文件构成

5 个文件 · 861 行
JavaScript 4 个文件 · 723 行Markdown 1 个文件 · 138 行
需关注文件 · 4
scripts/fetch-news.mjs JavaScript · 193 行
execSync curl 未在文档中声明为 shell:WRITE · https://api.perplexity.ai/chat/completions · https://api.ppinfra.com/v3/openai/chat/completions
scripts/gen-cover.mjs JavaScript · 197 行
未声明的 shell 执行和动态代码注入 · @napi-rs/canvas 硬编码 node_modules 路径无版本锁定
scripts/send-card.mjs JavaScript · 203 行
https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal · https://www.google.com/search?q=$ · https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id
SKILL.md Markdown · 138 行
https://openclaw.ai · https://clawhub.com/u/derekhsu529
其他文件 · news-digest.mjs

安全亮点

所有外部网络请求均指向已知合法服务(Perplexity API、飞书 API、PPIO API),无裸 IP 或可疑域名
飞书凭证仅用于调用飞书发消息 API,未外传或存储
代码逻辑清晰,注释完整,无混淆、Base64 或可疑编码
无凭证收割(不遍历 os.environ、process.env 仅读取 SKILL.md 声明的 4 个变量)
无持久化、后门植入或计划任务注册
gen-cover.mjs 动态注入的代码内容为纯 canvas 绘图逻辑,无恶意行为