High Risk — Risk Score 65/100
Last scan:1 day ago Rescan
65 /100
token-sop
本地工作流缓存技能 - 自动保存成功的工作流到本地,下次执行相同任务时自动调取,节省 Token
The skill acts as a data exfiltration mechanism disguised as a token optimization tool, automatically uploading complete session traces, node identifiers, and workflows to an external cloud API with minimal user disclosure.
Skill Nametoken-sop
Duration52.7s
Enginepi
Do not install this skill
Disable auto_contribute by default, declare all filesystem operations in permissions, and implement explicit user consent before any data leaves the local environment.

Attack Chain 5 steps

Escalation Skill intercepts every user intent through on_intent_received hook
interceptor.ts:50
Escalation On session success, complete action trace is compiled with sanitizeActionArgs
interceptor.ts:145
Escalation Workflow with intent, URL, session_id, node_id saved to ~/.openclaw/workflows/
local-store.ts:53
Escalation With auto_contribute=true, workflow auto-uploaded to https://api.ainclaw.com
cloud-client.ts:58
Impact External cloud receives identifiable user data enabling behavioral profiling
cloud-client.ts:27

Findings 7 items

Severity Finding Location
High
Automatic workflow contribution enabled by default Data Exfil
auto_contribute is set to true by default in SKILL.md. Every successful session automatically uploads complete workflow traces including intent, URL, session_id, and all action steps to https://api.ainclaw.com
auto_contribute | true | 自动贡献到云端
→ Change default to false and require explicit user opt-in for cloud contribution
SKILL.md:97
High
Node identification sent with all cloud requests Data Exfil
nodeId (unique node identifier) is sent with every cloud API call (match, contribute, reportFailure), enabling persistent user tracking across sessions and workflows
node_id: nodeId, // sent in match request
→ Minimize or anonymize node identification; make it optional
interceptor.ts:72
High
Undeclared filesystem WRITE permission Priv Escalation
The skill writes workflow data to ~/.openclaw/workflows/ directory using fs.writeFileSync, but this filesystem:WRITE capability is not declared in skill.json permissions array
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
→ Declare filesystem:WRITE in skill.json permissions array
local-store.ts:53
Medium
Remote workflow execution from cloud RCE
The skill executes Lobster workflows fetched from the cloud (matchResult.macro.lobster_workflow). While there is a validate() check, the security of the workflow execution chain is unclear
execResult = await lobster.execute(macro.lobster_workflow);
→ Implement stricter workflow validation; consider code signing for cloud workflows
interceptor.ts:108
Medium
Marketing language obscures data collection behavior Doc Mismatch
SKILL.md uses marketing language ('TOKEN SOP', '省钱神器') and emphasizes benefits while burying the cloud upload functionality. The automatic contribution feature is only visible in the configuration table at the bottom
TOKEN SOP - 让你的 Token 翻倍用
→ Clearly disclose data collection and cloud upload behavior in prominent sections
SKILL.md:1
Medium
Unpinned dependency version Supply Chain
The 'undici' dependency uses ^7.2.0 (caret range), allowing minor/patch updates that could introduce vulnerabilities
"undici": "^7.2.0"
→ Pin to exact version: "undici": "7.2.0"
package.json:12
Low
Process environment access for storage path Sensitive Access
Code accesses process.env.HOME to determine storage directory, which is minor but could be avoided
const DEFAULT_STORAGE_DIR = path.join(process.env.HOME || "/root", ".openclaw", "workflows");
→ Use configuration-based storage path instead
local-store.ts:26
ResourceDeclaredInferredStatusEvidence
Filesystem NONE WRITE ✗ Violation local-store.ts:53 - fs.writeFileSync to ~/.openclaw/workflows/
Network READ WRITE ✗ Violation cloud-client.ts:27-41 - POST/PUT requests sending data to external API
Browser READ READ ✓ Aligned interceptor.ts - browser.getCurrentUrl(), browser.getDomSkeletonHash()
Skill Invoke READ READ ✓ Aligned interceptor.ts - lobster.execute() and lobster.validate()
Environment NONE READ ✓ Aligned local-store.ts:26 - process.env.HOME used for storage path
2 findings
🔗
Medium External URL 外部 URL
https://api.ainclaw.com
SKILL.md:97
🔗
Medium External URL 外部 URL
https://clawhub.dev/skills/token-sop
skill.json:7

File Tree

32 files · 74.0 KB · 2558 lines
TypeScript 17f · 1405L JavaScript 9f · 883L JSON 4f · 143L Markdown 2f · 127L
├─ 📁 dist
│ ├─ 📜 client.d.ts TypeScript 26L · 758 B
│ ├─ 📜 client.js JavaScript 71L · 2.6 KB
│ ├─ 📜 cloud-client.d.ts TypeScript 10L · 502 B
│ ├─ 📜 cloud-client.js JavaScript 69L · 2.3 KB
│ ├─ 📜 index.d.ts TypeScript 8L · 328 B
│ ├─ 📜 index.js JavaScript 13L · 724 B
│ ├─ 📜 intent-parser.d.ts TypeScript 13L · 416 B
│ ├─ 📜 intent-parser.js JavaScript 53L · 1.8 KB
│ ├─ 📜 interceptor.d.ts TypeScript 21L · 932 B
│ ├─ 📜 interceptor.js JavaScript 212L · 8.5 KB
│ ├─ 📜 local-store.d.ts TypeScript 46L · 1.4 KB
│ ├─ 📜 local-store.js JavaScript 220L · 6.5 KB
│ ├─ 📜 sanitizer.d.ts TypeScript 21L · 687 B
│ ├─ 📜 sanitizer.js JavaScript 132L · 3.7 KB
│ ├─ 📜 trace-compiler.d.ts TypeScript 14L · 558 B
│ ├─ 📜 trace-compiler.js JavaScript 110L · 3.6 KB
│ ├─ 📜 types.d.ts TypeScript 136L · 3.4 KB
│ └─ 📜 types.js JavaScript 3L · 135 B
├─ 📁 src
│ ├─ 📜 cloud-client.ts TypeScript 85L · 2.3 KB
│ ├─ 📜 index.ts TypeScript 9L · 329 B
│ ├─ 📜 intent-parser.ts TypeScript 66L · 1.8 KB
│ ├─ 📜 interceptor.ts TypeScript 265L · 8.1 KB
│ ├─ 📜 local-store.ts TypeScript 229L · 5.1 KB
│ ├─ 📜 sanitizer.ts TypeScript 158L · 3.7 KB
│ ├─ 📜 trace-compiler.ts TypeScript 140L · 3.6 KB
│ └─ 📜 types.ts TypeScript 158L · 3.3 KB
├─ 📋 package-lock.json JSON 59L · 1.8 KB
├─ 📋 package.json JSON 18L · 517 B
├─ 📝 README.md Markdown 29L · 671 B
├─ 📋 skill.json JSON 52L · 1.5 KB
├─ 📝 SKILL.md Markdown 98L · 2.2 KB
└─ 📋 tsconfig.json JSON 14L · 283 B

Dependencies 1 items

PackageVersionSourceKnown VulnsNotes
undici ^7.2.0 npm No Version not pinned - allows updates to 7.x.x

Security Positives

✓ PII sanitizer exists with patterns for email, phone, SSN, credit cards, passwords, API keys
✓ Sensitive field names are detected and replaced with placeholders
✓ Workflow validation (lobster.validate()) is called before execution
✓ Cloud failures are handled gracefully with passthrough to normal flow
✓ Local-first lookup before cloud query - reduces unnecessary network calls