High Risk — Risk Score 68/100
Last scan:1 day ago Rescan
68 /100
skill-factory
Build and publish OpenClaw skills from recurring pain points
The skill uses undeclared shell execution, hardcoded suspicious paths, and remote npx code fetching without version pinning or integrity checks, with a doc-to-code mismatch on permissions.
Skill Nameskill-factory
Duration50.0s
Enginepi
Do not install this skill
Remove the hardcoded /opt/homebrew path and replace with a configurable or stdlib-only approach. Pin the clawhub version instead of using @latest. Declare all shell and network capabilities in SKILL.md.

Attack Chain 5 steps

Entry Skill masquerades as a legitimate OpenClaw tooling via SKILL.md
SKILL.md:1
Escalation Executes shell commands through undeclared execSync calls
scripts/factory.js:161
Escalation Runs remote npm package via npx @latest without pinning — fetches arbitrary code from the internet
scripts/factory.js:170
Escalation References suspicious hardcoded path /opt/homebrew/lib/node_modules/... suggesting platform-specific targeting
scripts/factory.js:163
Escalation User-controlled slug input could be exploited for path traversal to write outside skills/public/
scripts/factory.js:53

Findings 6 items

Severity Finding Location
High
Undeclared shell command execution via execSync RCE
The script uses child_process.execSync to run arbitrary shell commands (python3 and npx) without declaring shell execution capability in SKILL.md. This is the highest-value doc-to-code mismatch signal.
execSync(`python3 /opt/homebrew/lib/node_modules/openclaw/skills/skill-creator/scripts/package_skill.py "${resolvedDir}"`)
→ Declare shell:WRITE in the skill's allowed-tools. If shell execution is not a core feature, refactor to use Node.js stdlib only (e.g., fs for packaging).
scripts/factory.js:161
High
Suspicious hardcoded path referencing /opt/homebrew/ Obfuscation
A hardcoded absolute path /opt/homebrew/lib/node_modules/openclaw/skills/skill-creator/scripts/package_skill.py is used. This path pattern (/opt/homebrew) suggests macOS Homebrew targeting and is not declared in SKILL.md. It could be a planted backdoor path or a platform-specific dependency that may not exist.
execSync(`python3 /opt/homebrew/lib/node_modules/openclaw/skills/skill-creator/scripts/package_skill.py "${resolvedDir}"`
→ Replace hardcoded path with a configurable one or use a stdlib-only approach. If this is a legitimate dependency, declare it in a requirements/package.json.
scripts/factory.js:163
High
Remote code execution via npx @latest without version pinning Supply Chain
The publish function runs 'npx clawhub@latest publish' which fetches and executes remote npm code without a pinned version or hash verification. This is equivalent to curl|bash for the npm ecosystem — a critical supply chain risk.
execSync(`npx clawhub@latest publish "${resolvedDir}" --slug "${slug}" --name "${name}" --version 1.0.0 --tags "latest,agents"`)
→ Pin to a specific version (e.g., [email protected]) or verify the package integrity with a checksum. Document the expected clawhub CLI version.
scripts/factory.js:170
Medium
SKILL.md does not declare any allowed-tools or capability permissions Doc Mismatch
The SKILL.md frontmatter is missing allowed-tools declarations. The code uses filesystem:WRITE, shell:WRITE, and network:READ+EXECUTE, but SKILL.md declares none of these. This is a clear doc-to-code mismatch.
--- name: skill-factory description: "Build and publish OpenClaw skills..." ---
→ Add allowed-tools declaration to frontmatter listing Read and Bash (or equivalent) with justification for why each is needed.
SKILL.md:1
Medium
Arbitrary slug creation from user input could lead to path traversal Sensitive Access
The slugify() function converts a user-provided description into a directory name without sanitization for path traversal. While slugify removes non-alphanumeric chars, a crafted input like '../../../etc/cron.d' could write outside the intended skills/public/ directory.
return text.toLowerCase().replace(/[^a-z0-9\s-]/g, '').replace(/\s+/g, '-')...
→ Validate the generated slug stays within the skills/public/ boundary. Add path traversal checks after slugification.
scripts/factory.js:53
Low
No dependency pinning — zero stdlib-only constraint in package metadata Supply Chain
SKILL.md states the factory 'uses the LLM as the engine' but does not declare npm/node dependencies. The script uses only Node.js stdlib (fs, path, child_process), which is good, but no package.json or requirements.txt exists to lock the environment.
const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process');
→ Create a package.json pinning Node.js engine version. Ensure execSync calls reference only trusted, declared tools.
scripts/factory.js:1
ResourceDeclaredInferredStatusEvidence
Filesystem NONE WRITE ✗ Violation scripts/factory.js:122 fs.mkdirSync(...); scripts/factory.js:130 fs.writeFileSyn…
Network NONE READ+EXECUTE ✗ Violation scripts/factory.js:170 execSync('npx clawhub@latest publish...'); scripts/factor…
Shell NONE WRITE ✗ Violation scripts/factory.js:161 execSync('python3 ...'); scripts/factory.js:170 execSync(…
Environment NONE READ ✗ Violation scripts/factory.js:14 process.env.WORKSPACE; scripts/factory.js:15 process.env.C…

File Tree

2 files · 11.4 KB · 380 lines
JavaScript 1f · 274L Markdown 1f · 106L
├─ 📁 scripts
│ └─ 📜 factory.js JavaScript 274L · 8.2 KB
└─ 📝 SKILL.md Markdown 106L · 3.2 KB

Dependencies 2 items

PackageVersionSourceKnown VulnsNotes
npx (clawhub@latest) * (unpinned) npm remote No Remote code execution — no version pinning, no hash verification
python3 skill-creator unpinned /opt/homebrew/lib/node_modules/openclaw/... No Hardcoded path, not declared, platform-specific

Security Positives

✓ No base64-encoded strings or obfuscated code found in the implementation
✓ No credential harvesting or environment variable exfiltration detected
✓ No hardcoded IP addresses or external C2 communication endpoints found
✓ No cron/persistence mechanisms or startup hooks detected
✓ Script uses Node.js stdlib for core logic (fs, path) — no external npm dependencies needed for scaffolding