Back to skill

Security audit

Evonet

Security checks for vulnerabilities and agentic risk

Overview

This skill is broadly purpose-aligned, but it can upload local experience data and user-written posts to an external service with weaker disclosure, verification, and anonymization than its documentation claims.

Review this skill before installing. Use it only if you are comfortable sending local experience records, problem descriptions, and replies to EvolutionNet; avoid including secrets, logs, internal URLs, personal data, or proprietary details, and be especially cautious with the undocumented bulk upload behavior.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/evo_client.py:13
Finding
Incomplete anonymization permits sensitive information disclosure to an external service## Vulnerability Details **File Location**: `scripts/evo_client.py:13-20`, with data transmission sinks at `scripts/evo_client.py:72-84` and `scripts/evo_client.py:111-120` **Vulnerability Type**: Insufficient sensitive-data sanitization before external transmission **Risk Level**: Medium ### Technical Analysis The `sanitize()` function uses a narrow set of regular expressions: ```python def sanitize(text): """Anonymize sensitive info before sharing.""" if not text: return text text = re.sub(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', '[HIDDEN_IP]', text) text = re.sub(r'(/home/[a-zA-Z0-9_.-]+|C:\\Users\\[a-zA-Z0-9_.-]+)', '[LOCAL_PATH]', text) text = re.sub(r'(sk-[a-zA-Z0-9]{20,}|AKIA[A-Z0-9]{16})', '[HIDDEN_KEY]', text) return text ``` The resulting fields are transmitted to `https://evonet.live` by the following code: ```python payload = { "agent_id": ident['agent_id'], "agent_name": ident['name'], "experiences": [{ "question": sanitize(target.get('question', '')), "failure_reason": sanitize(target.get('failure_reason', '')), "improvement": sanitize(target.get('improvement', '')), "category": target.get('category', 'other') }] } print(f"Syncing experience '{exp_id}' to EvolutionNet...") result = api_request('/api/sync', payload) ``` The filters only recognize IPv4-like strings, two specific home-directory patterns, OpenAI-style keys beginning with `sk-`, and AWS access key IDs beginning with `AKIA`. They do not cover bearer tokens, passwords, private keys, session credentials, database connection strings, URLs containing credentials, email addresses, other API-key formats, macOS paths, general Unix paths, or sensitive personal names. In addition, `agent_name` is sent without sanitization. For matched home directories, only the `/home/user` or `C:\Users\user` prefix is replaced, potentially leaving sensitive path su ...[truncated 1414 chars]
Remediation
## Remediation Suggestions - Replace narrow denylist-based redaction with structured field allowlisting and data-minimization rules. - Add detection for common bearer tokens, private-key blocks, passwords, connection strings, cookies, authorization headers, URLs with embedded credentials, and a broader range of API-key formats. - Normalize and redact complete filesystem paths rather than only their home-directory prefix. - Treat `agent_name`, `category`, and every other transmitted field as potentially sensitive. - Display the exact sanitized payload before transmission and require explicit user confirmation. - Reject or quarantine records when high-entropy values or likely credentials remain after sanitization. - Add unit tests covering supported secret formats, path variants, multiline private keys, encoded secrets, and false-negative cases. - Update `SKILL.md` to describe anonymization as best-effort unless comprehensive controls can be guaranteed.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/evo_client.py:94
Finding
Undocumented bulk upload bypasses claimed experience-verification requirements## Vulnerability Details **File Location**: `scripts/evo_client.py:94-126`, with command registration at `scripts/evo_client.py:232` and dispatch at `scripts/evo_client.py:255-256` **Vulnerability Type**: Missing authorization and eligibility validation for bulk data export **Risk Level**: Medium ### Technical Analysis The `push_all()` function reads every nonempty entry from the local experience database and sends all records to the external service: ```python def push_all(): ident = get_identity() if not ident: return if not LOCAL_EXP_DB.exists(): print(f"Error: No local experience DB found at {LOCAL_EXP_DB}") return exps = [] with open(LOCAL_EXP_DB) as f: for line in f: line = line.strip() if line: exps.append(json.loads(line)) if not exps: print("No local experiences to share.") return payload = { "agent_id": ident['agent_id'], "agent_name": ident['name'], "experiences": [{ "question": sanitize(e.get('question', '')), "failure_reason": sanitize(e.get('failure_reason', '')), "improvement": sanitize(e.get('improvement', '')), "category": e.get('category', 'other') } for e in exps] } print(f"Syncing {len(exps)} experience(s) to EvolutionNet...") result = api_request('/api/sync', payload) if result: print(f"Success! Synced {result.get('count', 0)} experience(s).") ``` The bulk-upload command is exposed through the command-line interface: ```python sub.add_parser("push-all", help="Push all local experiences") ``` ```python elif args.cmd == "push-all": push_all() ``` No record is checked for a contrastive-test result, minimum weight, verified status, user approval, or any other eligibility condition. The single-record `push_experience()` path ...[truncated 1679 chars]
Remediation
## Remediation Suggestions - Remove `push-all` unless bulk synchronization is an explicit and necessary feature. - If retained, document the command and clearly state that it exports the entire local experience database. - Enforce a machine-verifiable eligibility rule for every record, such as a validated contrastive-test result, explicit `verified` flag, and minimum weight. - Fail closed when verification metadata is missing, malformed, or ambiguous. - Present a record count, identifiers, eligibility status, and exact sanitized payload before uploading. - Require explicit interactive confirmation for bulk transmission, with a separate noninteractive opt-in for controlled automation. - Add upload limits and support selecting an explicit list of record IDs. - Log which records were approved and transmitted without logging their sensitive contents. - Apply the same verification checks to both `push_experience()` and `push_all()` so the policy cannot be bypassed through an alternate command.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Lp1

High
Category
MCP Least Privilege
Confidence
94% confidence
Finding
This client performs outbound network communication to a third-party service but the capability is not reflected in declared permissions, which undermines user and platform trust boundaries. In an agent-skill context, undeclared network access is especially risky because local experience data, identities, and user-supplied content can be transmitted off-host without clear consent or policy enforcement.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The post_problem function sends user-provided title and description directly to a remote server without any meaningful privacy warning, consent step, or sanitization. Because users may include sensitive operational details when describing a problem, this can cause unintended disclosure of confidential information to an external service.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The reply_to_problem function uploads arbitrary user-supplied reply content to the remote service with no transmission warning or privacy controls. In collaborative support workflows, replies often contain logs, credentials, environment details, or internal URLs, making silent external posting a realistic data-leak vector.

Static analysis

No suspicious patterns detected.