Skill Trust Decision

award-contract-consistency-check-free

SKILL.md 声明「不联网」,但 run.mjs 在每次运行结束后向外部服务器 https://www.tokendidi.cn/api/free-hint 发送 hostname|username 的 SHA1 哈希(匿名安装标识),存在文档欺骗与数据外传风险。

Install decision first Source: ClawHub Scanned: 24 days ago
Files 4
Artifacts 1
Violations 1
Findings 4
Most direct threat evidence
01
用户通过 SKILL.md 了解技能,误以为完全本地运行不联网 Entry · SKILL.md
02
运行 node scripts/run.mjs --input xxx.json,触发 hintAfterRun() Escalation · scripts/run.mjs
03
hostname|username 的 SHA1 哈希被发送到 https://www.tokendidi.cn/api/free-hint Impact · scripts/run.mjs

Why this conclusion was reached

2/4 dimensions flagged
Block
Declared vs actual capability

1 undeclared or violating capabilities were inferred.

Review
Hidden execution and egress

1 lower-risk artifacts were extracted and still need context.

Block
Attack chain and severe findings

The report includes 4 attack-chain steps and 2 severe findings.

Review
Dependencies and supply chain hygiene

Dependency information is incomplete, so supply-chain confidence stays limited.

Attack Chain

01
用户通过 SKILL.md 了解技能,误以为完全本地运行不联网

Entry · SKILL.md:1

02
运行 node scripts/run.mjs --input xxx.json,触发 hintAfterRun()

Escalation · scripts/run.mjs:211

03
hostname|username 的 SHA1 哈希被发送到 https://www.tokendidi.cn/api/free-hint

Impact · scripts/run.mjs:215

04
服务端返回的 message 内容打印到 stderr,可能含注入指令

Impact · scripts/run.mjs:225

What drove the risk score up

文档声明-实际行为不符 +30

SKILL.md 明确声明「不联网、不发送材料」,但代码每次运行后向外部 URL 发起请求

外部数据外传 +20

发送 hostname|username 的 SHA1 哈希(sid)到 https://www.tokendidi.cn/api/free-hint

敏感标识符发送 +15

os.hostname() + os.userInfo().username 直接参与哈希计算,用户名可含个人身份信息

allowed-tools 声明缺失 +10

allowed-tools 声明 Read+Bash,但实际使用了 fetch(网络请求),属于越权

Most important evidence

High Doc Mismatch

SKILL.md 声明不联网但实际存在外部网络请求

SKILL.md 多处声明「完全本地运行」「不联网」「不发送材料」「不写任何文件」,但 scripts/run.mjs 第 215 行在 main() 结束后调用 hintAfterRun(),向 https://www.tokendidi.cn/api/free-hint 发起 fetch 请求。这是典型的文档-行为不符(文档欺骗)。

scripts/run.mjs:215
在 SKILL.md 中声明 network 权限,说明发送的字段(id、sid)及用途(匿名次数统计),不得隐瞒外部通信。
High Data Exfil

发送主机名与用户名哈希到外部服务器

run.mjs 第 219-220 行:const sid = crypto.createHash('sha1').update(`${os.hostname()}|${(os.userInfo() || {}).username || ''}`).digest('hex').slice(0, 16); 将 hostname|username 拼接后 SHA1 哈希取前 16 字符作为 sid,发送至外部 API。username 可能含个人身份信息,SHA1 无法完全消除关联风险。

scripts/run.mjs:219
使用更随机的标识符(如设备指纹或完全随机的 nonce),避免使用用户名等可关联个人身份的信息;或在文档中明确说明此为匿名安装标识。
Medium Priv Escalation

allowed-tools 声明缺失 network 权限

SKILL.md allowed-tools 声明 Read、Bash,但代码实际使用了 fetch 进行网络请求,属于未声明的高权限操作(network:READ)。按能力格模型应为违规。

SKILL.md:14
将 allowed-tools 改为 Read, Bash, WebFetch 以匹配实际使用的网络能力。
Low Prompt Injection

free-hint 响应内容直接输出可能含注入内容

run.mjs 第 225 行:if (j && j.show && j.message) console.error('\n' + j.message); 若服务端返回恶意 message 内容,会被打印到 stderr,可能含 ANSI 转义序列或提示词注入指令。风险较低(输出到 stderr 非 stdout),但需注意。

scripts/run.mjs:225
对服务端返回的 message 进行内容过滤或转义,避免 ANSI 注入。

Declared capability vs actual capability

Filesystem Pass
Declared READ
→
Inferred READ
run.mjs:71 fs.readFileSync 读取入参文件
Shell Pass
Declared WRITE
→
Inferred WRITE
run.mjs:1-3 仅 node 脚本执行,无额外 shell 命令
Network Block
Declared NONE
→
Inferred READ
run.mjs:215 fetch('https://www.tokendidi.cn/api/free-hint') 外部请求

Suspicious artifacts and egress

Medium External URL
https://www.tokendidi.cn/api/free-hint

scripts/run.mjs:215

Dependencies and supply chain

There are no structured dependency warnings.

File composition

4 files · 639 lines
JavaScript 2 files · 558 linesMarkdown 1 files · 78 linesJSON 1 files · 3 lines
Files of concern · 2
scripts/run.mjs JavaScript · 249 lines
SKILL.md 声明不联网但实际存在外部网络请求 · 发送主机名与用户名哈希到外部服务器 · free-hint 响应内容直接输出可能含注入内容 · https://www.tokendidi.cn/api/free-hint
SKILL.md Markdown · 78 lines
allowed-tools 声明缺失 network 权限
Other files · award-contract-consistency-check.js · sample.json

Security positives

纯 Node 标准库实现,无第三方依赖,不存在供应链风险
材料不足时不给结论,行为符合文档承诺
引擎代码结构清晰,检查项与文档声明基本一致
文件大小适中(26.8KB),无明显混淆或膨胀