Suspicious — Risk Score 45/100
Last scan:2 days ago Rescan
45 /100
capability-evolver-zc
A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.
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.
Skill Namecapability-evolver-zc
Duration96.9s
Enginepi
Use with caution
1) Document all execSync usages in SKILL.md (git, health checks, clawhub, process enumeration). 2) Declare network access to evomap.ai endpoints (A2A_HUB_URL). 3) Remove hardcoded credentials from test/sanitize.test.js or use environment-variable substitution. 4) Verify sanitizePayload truly redacts all credential patterns before hub publishing. 5) Consider adding the 3 dangerous shell commands to a deny-list alongside the existing allow-list in validation filtering.

Findings 9 items

Severity Finding Location
Medium
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.
const { execSync } = require('child_process'); ... execSync('pgrep -c node', ...) ... execSync(`${clawhubBin} update ${slug} --force`, ...)
→ Add a 'Declared Shell Commands' section to SKILL.md listing: git, pgrep/ps/tasklist, clawhub, INTEGRATION_STATUS_CMD. Alternatively, add shell:NONE declaration and remove execSync dependencies.
src/evolve.js:1
Medium
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.
function httpTransportSend(message, opts) { var endpoint = hubUrl.replace(/\/+$/, '') + '/a2a/' + message.message_type; return fetch(endpoint, { method: 'POST', ... }); }
→ Declare network:WRITE in SKILL.md with endpoints: evomap.ai/a2a/* (heartbeat, fetch, publish, report, decision, revoke). Mention data published includes sanitized Gene+Capsule bundles.
src/gep/a2aProtocol.js:1
Medium
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.
hostname: crypto.createHash('sha256').update(os.hostname()).digest('hex').slice(0, 12), cwd: crypto.createHash('sha256').update(process.cwd()).digest('hex').slice(0, 12)
→ Document in SKILL.md that environment fingerprints (hashed identifiers) are collected and published to the hub. Consider using a privacy-preserving fingerprint that doesn't include cwd paths.
src/gep/envFingerprint.js:1
Medium
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.
const AGENT_SESSIONS_DIR = path.join(os.homedir(), `.openclaw/agents/${AGENT_NAME}/sessions`);
→ Document in SKILL.md that session logs from ~/.openclaw/agents/ are read. Add sanitization note explaining that credentials in session logs are redacted before use in prompts.
src/evolve.js:1
Medium
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.
if (process.env.INTEGRATION_STATUS_CMD) { const status = execSync(process.env.INTEGRATION_STATUS_CMD, { encoding: 'utf8', ... }); }
→ Either remove INTEGRATION_STATUS_CMD dynamic execution, or document it prominently in SKILL.md as an allowed arbitrary command execution vector.
src/evolve.js:1
Medium
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.
validation: ['node test.js', 'rm -rf /', 'echo $(whoami)', 'npm test']
→ Add 'rm -rf' and other destructive patterns to the deny-list in addition to the current allow-list prefix approach.
test/skillDistiller.test.js:210
Low
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.
assert.strictEqual(redactString('sk-abcdefghijklmnopqrstuvwxyz'), REDACTED);
→ Use synthetic/fictional credentials that don't match real patterns, or generate them dynamically in tests.
test/sanitize.test.js:10
Low
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.
fs.writeFileSync(NODE_SECRET_FILE, secret, { encoding: 'utf8', mode: 0o600 });
→ Consider using OS keychain (e.g., keytar) for node secret storage instead of plaintext files.
src/gep/a2aProtocol.js:1
Low
EVOLVE_ALLOW_SELF_MODIFY enables evolver self-modification
Setting EVOLVE_ALLOW_SELF_MODIFY=true allows the evolver to modify its own source code (skills/evolver/). SKILL.md warns this is dangerous, but the mechanism exists and could be exploited if an attacker gains environment variable control.
var allowSelfModify = String(process.env.EVOLVE_ALLOW_SELF_MODIFY || '').toLowerCase() === 'true';
→ Document this as a dangerous capability requiring explicit opt-in, and consider requiring a second-factor confirmation for self-modification.
src/gep/solidify.js:1
ResourceDeclaredInferredStatusEvidence
Filesystem NONE WRITE ✗ Violation src/gep/solidify.js:execSync calls git reset/hard, git restore, git clean; index…
Shell NONE WRITE ✗ Violation src/evolve.js:execSync for git/ps/pgrep/tasklist/df/clawhub; src/gep/solidify.js…
Network NONE WRITE ✗ Violation src/gep/a2aProtocol.js:sendHeartbeat POST to A2A_HUB_URL every 6min; hubSearch (…
Environment NONE READ ✗ Violation src/gep/envFingerprint.js captures hostname hash, device_id, platform, node_vers…
Skill Invoke NONE READ ✗ Violation src/evolve.js reads session logs from ~/.openclaw/agents/*/sessions/; src/gep/br…
5 Critical 14 findings
🔑
Critical API Key 硬编码 API 密钥
sk-abcdefghijklmnopqrstuvwxyz
test/sanitize.test.js:10
🔑
Critical API Key 硬编码 API 密钥
ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
test/sanitize.test.js:19
🔑
Critical API Key 硬编码 API 密钥
gho_abcdefghijklmnopqrstuvwxyz1234567890
test/sanitize.test.js:21
🔑
Critical API Key 硬编码 API 密钥
AKIAIOSFODNN7EXAMPLE
test/sanitize.test.js:29
💀
Critical Dangerous Command 危险 Shell 命令
rm -rf /
test/skillDistiller.test.js:210
🔗
Medium External URL 外部 URL
https://evomap.ai
README.md:5
🔗
Medium External URL 外部 URL
https://evomap.ai/wiki
README.md:5
🔗
Medium External URL 外部 URL
https://api.star-history.com/svg?repos=autogame-17/evolver&type=Date
README.md:255
🔗
Medium External URL 外部 URL
https://star-history.com/#autogame-17/evolver&Date
README.md:255
🔗
Medium External URL 外部 URL
https://mowen.cn
README.md:270
🔗
Medium External URL 外部 URL
https://evomap.ai/claim/
SKILL.md:45
🔗
Medium External URL 外部 URL
https://www.clawhub.ai
scripts/publish_public.js:410
📧
Info Email 邮箱地址
[email protected]
test/sanitize.test.js:57
📧
Info Email 邮箱地址
[email protected]
test/sanitize.test.js:74

File Tree

76 files · 601.1 KB · 16419 lines
JavaScript 68f · 15543L Markdown 4f · 655L JSON 4f · 221L
├─ 📁 assets
│ └─ 📁 gep
│ ├─ 📋 capsules.json JSON 79L · 2.8 KB
│ └─ 📋 genes.json JSON 108L · 3.5 KB
├─ 📁 scripts
│ ├─ 📜 a2a_export.js JavaScript 63L · 2.3 KB
│ ├─ 📜 a2a_ingest.js JavaScript 79L · 2.6 KB
│ ├─ 📜 a2a_promote.js JavaScript 118L · 4.7 KB
│ ├─ 📜 analyze_by_skill.js JavaScript 121L · 4.7 KB
│ ├─ 📜 build_public.js JavaScript 355L · 10.6 KB
│ ├─ 📜 extract_log.js JavaScript 85L · 2.5 KB
│ ├─ 📜 generate_history.js JavaScript 75L · 2.5 KB
│ ├─ 📜 gep_append_event.js JavaScript 96L · 3.0 KB
│ ├─ 📜 gep_personality_report.js JavaScript 234L · 7.7 KB
│ ├─ 📜 human_report.js JavaScript 147L · 5.7 KB
│ ├─ 📜 publish_public.js JavaScript 614L · 19.9 KB
│ ├─ 📜 recover_loop.js JavaScript 61L · 1.7 KB
│ ├─ 📜 suggest_version.js JavaScript 89L · 3.0 KB
│ └─ 📜 validate-modules.js JavaScript 8L · 437 B
├─ 📁 src
│ ├─ 📁 gep
│ │ ├─ 📜 a2a.js JavaScript 173L · 6.3 KB
│ │ ├─ 📜 a2aProtocol.js JavaScript 672L · 20.9 KB
│ │ ├─ 📜 analyzer.js JavaScript 35L · 988 B
│ │ ├─ 📜 assetCallLog.js JavaScript 130L · 3.4 KB
│ │ ├─ 📜 assets.js JavaScript 36L · 1.1 KB
│ │ ├─ 📜 assetStore.js JavaScript 297L · 11.3 KB
│ │ ├─ 📜 bridge.js JavaScript 71L · 2.0 KB
│ │ ├─ 📜 candidates.js JavaScript 142L · 5.0 KB
│ │ ├─ 📜 contentHash.js JavaScript 65L · 2.1 KB
│ │ ├─ 📜 deviceId.js JavaScript 209L · 6.6 KB
│ │ ├─ 📜 envFingerprint.js JavaScript 68L · 2.3 KB
│ │ ├─ 📜 hubReview.js JavaScript 206L · 6.4 KB
│ │ ├─ 📜 hubSearch.js JavaScript 237L · 7.7 KB
│ │ ├─ 📜 issueReporter.js JavaScript 262L · 8.8 KB
│ │ ├─ 📜 llmReview.js JavaScript 92L · 3.1 KB
│ │ ├─ 📜 memoryGraph.js JavaScript 771L · 26.9 KB
│ │ ├─ 📜 memoryGraphAdapter.js JavaScript 203L · 7.0 KB
│ │ ├─ 📜 mutation.js JavaScript 186L · 6.7 KB
│ │ ├─ 📜 narrativeMemory.js JavaScript 108L · 3.7 KB
│ │ ├─ 📜 paths.js JavaScript 108L · 3.0 KB
│ │ ├─ 📜 personality.js JavaScript 355L · 13.2 KB
│ │ ├─ 📜 prompt.js JavaScript 566L · 22.6 KB
│ │ ├─ 📜 questionGenerator.js JavaScript 212L · 8.5 KB
│ │ ├─ 📜 reflection.js JavaScript 127L · 4.2 KB
│ │ ├─ 📜 sanitize.js JavaScript 67L · 2.2 KB
│ │ ├─ 📜 selector.js JavaScript 250L · 9.2 KB
│ │ ├─ 📜 signals.js JavaScript 417L · 19.5 KB
│ │ ├─ 📜 skillDistiller.js JavaScript 499L · 19.5 KB
│ │ ├─ 📜 solidify.js JavaScript 1651L · 69.1 KB
│ │ ├─ 📜 strategy.js JavaScript 126L · 4.4 KB
│ │ ├─ 📜 taskReceiver.js JavaScript 432L · 14.0 KB
│ │ └─ 📜 validationReport.js JavaScript 55L · 2.1 KB
│ ├─ 📁 ops
│ │ ├─ 📜 cleanup.js JavaScript 80L · 2.5 KB
│ │ ├─ 📜 commentary.js JavaScript 60L · 1.7 KB
│ │ ├─ 📜 health_check.js JavaScript 106L · 4.0 KB
│ │ ├─ 📜 index.js JavaScript 11L · 376 B
│ │ ├─ 📜 innovation.js JavaScript 67L · 3.1 KB
│ │ ├─ 📜 lifecycle.js JavaScript 168L · 6.2 KB
│ │ ├─ 📜 self_repair.js JavaScript 72L · 2.5 KB
│ │ ├─ 📜 skills_monitor.js JavaScript 143L · 5.3 KB
│ │ └─ 📜 trigger.js JavaScript 33L · 837 B
│ ├─ 📜 canary.js JavaScript 13L · 486 B
│ └─ 📜 evolve.js JavaScript 1676L · 64.0 KB
├─ 📁 test
│ ├─ 📜 a2aProtocol.test.js JavaScript 134L · 4.4 KB
│ ├─ 📜 contentHash.test.js JavaScript 106L · 3.5 KB
│ ├─ 📜 envFingerprint.test.js JavaScript 89L · 3.0 KB
│ ├─ 📜 mutation.test.js JavaScript 142L · 4.6 KB
│ ├─ 📜 sanitize.test.js JavaScript 90L · 3.9 KB
│ ├─ 📜 selector.test.js JavaScript 124L · 4.1 KB
│ ├─ 📜 signals.test.js JavaScript 217L · 9.9 KB
│ ├─ 📜 skillDistiller.test.js JavaScript 486L · 16.9 KB
│ ├─ 📜 strategy.test.js JavaScript 133L · 4.8 KB
│ └─ 📜 validationReport.test.js JavaScript 148L · 4.8 KB
├─ 📋 _meta.json JSON 5L · 141 B
├─ 📝 CONTRIBUTING.md Markdown 11L · 327 B
├─ 📜 index.js JavaScript 472L · 19.1 KB
├─ 📋 package.json JSON 29L · 784 B
├─ 📝 README.md Markdown 276L · 12.0 KB
├─ 📝 README.zh-CN.md Markdown 236L · 11.3 KB
└─ 📝 SKILL.md Markdown 132L · 5.3 KB

Dependencies 2 items

PackageVersionSourceKnown VulnsNotes
dotenv ^16.4.7 npm No Version pinned
all-dependencies-pinned true npm No All dependencies in package.json have pinned versions

Security Positives

✓ Comprehensive sanitization pipeline (sanitize.js) redacts API keys, tokens, private keys, paths, emails, and .env references before hub publishing
✓ Ethics enforcement in checkConstraints() blocks strategies attempting safety bypass, covert monitoring, social engineering, or transparency violations
✓ Blast radius hard caps (60 files / 20000 lines) cannot be overridden by genes — system-level safety guard
✓ Critical path protection prevents evolver from modifying protected skill directories (feishu-*, clawhub, git-sync, evolver)
✓ Validation command allow-list restricts execution to 'node ', 'npm ', 'npx ' prefixes with shell operator blocking
✓ Canary check (runCanaryCheck) verifies index.js loads in an isolated child process before solidify commits changes
✓ Optional LLM review gate (EVOLVER_LLM_REVIEW) can reject changes before commit
✓ Auto-rollback on failure (EVOLVER_ROLLBACK_MODE=stash/hard) prevents accumulation of bad changes
✓ Dormant hypothesis system preserves partial state during backoff to prevent data loss
✓ Repair loop circuit breaker prevents infinite repair-retry cycles
✓ Memory graph integrity check throws if causal memory cannot be written, refusing to evolve blindly
✓ Dependency scan: no known-vulnerable packages detected, all npm dependencies are pinned