Back to skill

Security audit

Robust Agent Design

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent robustness-design guide, but its reference template includes under-scoped file persistence that can overwrite arbitrary writable paths if adopted as-is.

Review before installing or reusing the reference code. Treat the Python files as illustrative templates, not production-safe code: make disk persistence opt-in, restrict state paths to an application-owned directory, use safe file creation permissions, validate loaded state, and do not rely on the sample checksum for security integrity.

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
references/agent_template.py:69
Finding

Configurable State Path Enables Arbitrary File Overwrite and Unsafe Temporary-File Access

Content
View full analysis
Optional[Dict]: """Load state""" if self.state_persistence == 'file': try: with open(self.state_file, 'r') as f: return json.load(f) except FileNotFoundError: return None elif self.state_persistence == 'memory': return getattr(self, '_memory_state', None) return None ``` ### Technical Analysis The agent accepts `state_file` directly from its configuration and passes that path to `open()` for reading and writing. It does not constrain the path to an application-controlled directory, canonicalize and validate it, reject symbolic links, or enforce restrictive file permissions. The default path is under the shared `/tmp` directory. Although the randomly generated UUID makes casual prediction difficult, the implementation does not use secure temporary-file primitives or atomic creation. A caller able to supply configuration can bypass the random default entirely and select an arbitrary path. Opening the state file in `w` mode follows symbolic links ...[truncated 1674 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
references/agent_template.py:87
Finding

Truncated Unkeyed MD5 Does Not Provide the Claimed State Integrity Protection

Content
View full analysis
Optional[Dict]: """Load state""" if self.state_persistence == 'file': try: with open(self.state_file, 'r') as f: return json.load(f) except FileNotFoundError: return None elif self.state_persistence == 'memory': return getattr(self, '_memory_state', None) return None def _compute_checksum(self, data: Any) -> str: """Compute data checksum""" import hashlib if data is None: return "" data_str = json.dumps(data, sort_keys=True, default=str) return hashlib.md5(data_str.encode()).hexdigest()[:8] ``` ### Technical Analysis The state record stores only the first eight hexadecimal characters of an MD5 digest, providing 32 bits of checksum space. MD5 is unsuitable for security-sensitive integrity verification, and truncating it further increases collision feasibility. More importantly, this value is unkeyed. Any party able to modify the underlying state or input can calculate a replacement digest. The `_load_state()` method merely parses and returns JSON; it does not recalculate or compare the checksum, validate an authe ...[truncated 1653 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill includes code and design guidance that clearly performs state persistence via file/database storage, but the manifest does not declare any explicit tool scope such as permissions or allowed-tools. In an agent ecosystem, this creates an implicit capability gap where the skill may be invoked without transparent user/operator awareness of its read/write needs, increasing the risk of over-privileged execution or unsafe adaptation by a host agent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The activation language is broad enough to trigger on general requests involving architecture, robustness, retries, or state management, which can cause this skill to be selected in situations beyond its intended narrow use. Over-broad matching is dangerous because it can unexpectedly introduce persistence and fault-handling patterns, including file-backed state behavior, into unrelated tasks and expand the operational surface area without clear user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The agent persists metadata, retry state, timestamps, error details, and an input-derived checksum to a predictable file under /tmp by default, without user notice or protective controls. In multi-user or shared environments, this can expose sensitive task metadata, enable unintended information disclosure, and create opportunities for tampering or symlink-based file attacks depending on runtime context.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The chain advertises automatic rollback, but _rollback() invokes rollback callbacks with action.params instead of the runtime result or a structured execution context. In this file, several rollback handlers depend on identifiers produced during execution, so failed compensation can leave partial state changes in place and undermine the reliability guarantees this pattern is meant to provide.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The rollback for the 'Log failure' action is defined as lambda log_id: ..., but the framework calls rollbacks with the original params {'error': e, 'email': email_data}. If a later compensation step fails, this rollback will raise due to the signature mismatch, preventing cleanup and leaving logged user-related failure data behind despite the example claiming successful compensation behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The compensation flow logs failure information together with email context, which can include user-related data such as recipient information and message metadata. The code labels this as logging but does not explicitly disclose in comments or documentation that user data and error context will be retained in logs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This code performs a safety-relevant notification action by sending an SMS using a phone number and message content derived from user data. Although the file contains console prints about the overall flow, there is no docstring, comment, or user-facing warning near this operation disclosing that a fallback SMS containing user-related information may be sent.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The manifest frames this skill as applying robust design patterns for building fault-tolerant, state-driven systems, which suggests architectural guidance or template logic. This implementation goes beyond pure design illustration by defaulting to writing execution state to /tmp and persisting task-derived metadata to disk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest is about robust agent architecture, fault tolerance, retries, and state management. Including a CrawlerAgent example with URL-oriented crawling behavior adds an application-domain capability unrelated to the core design-pattern purpose, even if the network activity is simulated here.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.