capability-evolver-zc
The skill has extensive undeclared shell execution, undeclared external network calls to evomap.ai, and stores hardcoded credentials in test files — a significant doc-to-code mismatch across filesystem, shell, and network resources.
Why this conclusion was reached
2/4 dimensions flagged5 undeclared or violating capabilities were inferred.
5 high-risk artifacts or egress signals were extracted.
There is no explicit malicious chain in the report.
2 dependency or supply-chain issues need attention.
What drove the risk score up
SKILL.md declares no shell access, but execSync is used for git diff/status, process enumeration (ps/pgrep/tasklist), df, clawhub update, and INTEGRATION_STATUS_CMD — completely undeclared
SKILL.md setup section mentions node registration but A2A_HUB_URL network calls (heartbeat every 6min, fetch, publish, report, review) are not declared as capabilities
test/sanitize.test.js contains 5 hardcoded API keys (OpenAI sk-, GitHub ghp_/gho_, AWS AKIAIOSFODNN7EXAMPLE) — test artifact but poor security hygiene
test/skillDistiller.test.js:210 contains 'rm -rf /' as a validation-filter test case; filtered by allow-list but represents a dangerous corpus entry
Most important evidence
Undeclared shell command execution throughout codebase
SKILL.md declares no shell access, yet execSync is used extensively: git diff/status/reset/checkout operations, process enumeration (ps, pgrep, tasklist), filesystem df, clawhub update, and INTEGRATION_STATUS_CMD dynamic execution. These capabilities are completely absent from the SKILL.md capability declaration section.
src/evolve.js:1 Undeclared external network communications to evomap.ai
The skill connects to evomap.ai (via A2A_HUB_URL) for: heartbeat every 6 minutes (sendHeartbeat), hub search (hubSearch), asset publishing (httpTransportSend), task fetching, hub review submission, and hello registration. None of these network operations are declared in SKILL.md.
src/gep/a2aProtocol.js:1 Environment fingerprinting sent to external hub
captureEnvFingerprint() in envFingerprint.js collects: device_id (computed from ~/.evomap/device-id), hostname (hashed), node version, platform, arch, OS release, cwd (hashed), and container status. This is embedded in every Capsule and EvolutionEvent, and published to the hub.
src/gep/envFingerprint.js:1 Session log reading from agent home directory
The evolver reads session logs from ~/.openclaw/agents/${AGENT_NAME}/sessions/*.jsonl, which may contain sensitive conversation data, tool results, and credentials passed as arguments. While the skill filters some sensitive content, raw session data is parsed and used in evolution reasoning.
src/evolve.js:1 Dynamic command execution via INTEGRATION_STATUS_CMD env var
When INTEGRATION_STATUS_CMD is set as an environment variable, execSync executes its value as a shell command. This is an indirect RCE vector if an attacker can set this environment variable — the evolver will execute arbitrary commands and include the output in the health report.
src/evolve.js:1 Validation command allow-list has narrow coverage — dangerous commands present in test corpus
The validation command filter in validateSynthesizedGene() and isValidationCommandAllowed() only allows 'node ', 'npm ', 'npx ' prefixes and blocks shell operators. However, test/skillDistiller.test.js:210 includes 'rm -rf /' as a test input for this filter, confirming that dangerous commands ARE part of the input corpus. While the filter correctly blocks it, the presence of such commands in distillation inputs is alarming.
test/skillDistiller.test.js:210 Hardcoded API credentials in test file
test/sanitize.test.js contains 5 hardcoded API key patterns: OpenAI sk- key, GitHub ghp_ and gho_ tokens, AWS AKIAIOSFODNN7EXAMPLE, and others. These are used as test inputs for the redactString function. While they are test artifacts (not production credentials), storing real-looking credentials in source code is poor security hygiene.
test/sanitize.test.js:10 Node secret stored in plaintext on filesystem
A2A_NODE_SECRET is persisted to ~/.evomap/node_secret with mode 0o600. While the permission is restrictive, the secret is stored in plaintext on disk and used as an HMAC key for signing published assets.
src/gep/a2aProtocol.js:1 1 more findings are not expanded here
Declared capability vs actual capability
src/gep/solidify.js:execSync calls git reset/hard, git restore, git clean; index.js --review mode calls git checkout; src/evolve.js writes to workspace via LLM prompts src/evolve.js:execSync for git/ps/pgrep/tasklist/df/clawhub; src/gep/solidify.js:runCmd execSync for git; src/gep/a2aProtocol.js:httpTransportSend uses Node.js fetch API for network; All undeclared in SKILL.md src/gep/a2aProtocol.js:sendHeartbeat POST to A2A_HUB_URL every 6min; hubSearch (src/gep/hubSearch.js) fetches from hub; httpTransportSend publishes sanitized assets; All external network calls undeclared in SKILL.md src/gep/envFingerprint.js captures hostname hash, device_id, platform, node_version, cwd hash; src/gep/a2aProtocol.js reads A2A_NODE_ID, A2A_HUB_URL, A2A_NODE_SECRET, AGENT_NAME src/evolve.js reads session logs from ~/.openclaw/agents/*/sessions/; src/gep/bridge.js renders prompt artifacts for LLM to execute arbitrary code Suspicious artifacts and egress
sk-abcdefghijklmnopqrstuvwxyz test/sanitize.test.js:10
ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx test/sanitize.test.js:19
gho_abcdefghijklmnopqrstuvwxyz1234567890 test/sanitize.test.js:21
AKIAIOSFODNN7EXAMPLE test/sanitize.test.js:29
rm -rf / test/skillDistiller.test.js:210
https://evomap.ai README.md:5
https://evomap.ai/wiki README.md:5
https://api.star-history.com/svg?repos=autogame-17/evolver&type=Date README.md:255
https://star-history.com/#autogame-17/evolver&Date README.md:255
https://mowen.cn README.md:270
https://evomap.ai/claim/ SKILL.md:45
https://www.clawhub.ai scripts/publish_public.js:410
Dependencies and supply chain
| Package | Version | Source | Known vuln | Notes |
|---|---|---|---|---|
| dotenv | ^16.4.7 | npm | No | Version pinned |
| all-dependencies-pinned | true | npm | No | All dependencies in package.json have pinned versions |
File composition
src/gep/solidify.js src/evolve.js src/gep/a2aProtocol.js scripts/publish_public.js test/skillDistiller.test.js