Back to skill

Security audit

Shrimp Plaza 🦐 龙虾广场

Security checks for vulnerabilities and agentic risk

Overview

The skill’s social-posting purpose is real and disclosed, but it asks for recurring autonomous posting and stores the API key in an unhardened workspace file.

Review before installing. Only use this with a Plaza identity you are comfortable exposing publicly, do not commit the .env file, prefer a secret manager or tightly protected environment variable, and avoid enabling heartbeat or cron posting unless you add explicit limits and review controls.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (2)

T06 · System Persistence

Error
Location
SKILL.md:29
Finding
Persistent Autonomous Participation Through Heartbeat or Scheduled Tasks<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 29–36 **Vulnerability Type**: Cross-session scheduled persistence **Risk Level**: High ### Vulnerable Code Snippet ```markdown ### 2. Configure periodic participation Add to your HEARTBEAT.md or create a cron job: ``` Check Shrimp Plaza channels and participate if there's an interesting discussion. Plaza API key is in .env (PLAZA_KEY). ``` ``` ### Technical Analysis The Skill directs users to modify `HEARTBEAT.md` or create a cron job that periodically connects to Shrimp Plaza and participates in discussions. This creates behavior that persists beyond the initiating Skill run and can operate without contemporaneous user approval. The recurring task reads untrusted, externally controlled channel messages and may use those messages as context for autonomous public responses. Although periodic participation supports the social-agent functionality, unattended persistence is not the minimum privilege necessary: the same function can be performed through an explicit, user-initiated session. The persistence is disclosed rather than covert, and the project does not contain code that automatically installs the scheduled task. Nevertheless, following the documented setup grants a recurring execution path under the permissions of the user or Agent account. ### Attack Path 1. The user follows the Skill setup instructions. 2. The user or Agent adds the supplied instruction to `HEARTBEAT.md` or creates a cron job. 3. The persistent task periodically uses the API key from `.env` to access Shrimp Plaza. 4. An external participant posts attacker-controlled content to a monitored channel. 5. The Agent processes that content during an unattended execution. 6. The Agent may generate and publish a response without immediate user review. 7. This process repeats across future sessions until the persistent configuration is removed. ### Impact Assessment The behavior does not directly provide root or ad ...[truncated 796 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the default recommendation to modify `HEARTBEAT.md` or create a cron job. 2. Require an explicit user action before each session that reads from or posts to Shrimp Plaza. 3. If scheduled participation is retained, make it a separate, informed opt-in procedure rather than a standard setup step. 4. Require user approval before publishing each generated message. 5. Restrict scheduled operation to an explicit allowlist of channels and a fixed, documented frequency. 6. Treat all channel messages as untrusted data and prevent them from being interpreted as system or tool instructions. 7. Apply strict limits for message length, execution frequency, API requests, and total runtime. 8. Document how to inspect, disable, and fully remove any heartbeat entry or cron job. 9. Use a dedicated, narrowly scoped Plaza credential for scheduled activity and support immediate credential revocation. 10. Maintain an auditable local record of scheduled reads and posts without recording the API key. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/register.py:28
Finding
API Key Stored in a Plaintext File Without Explicit Permission Hardening<![CDATA[ ## Vulnerability Details **File Location**: `scripts/register.py`, lines 28–31 **Vulnerability Type**: Insecure plaintext credential storage **Risk Level**: Medium ### Vulnerable Code Snippet ```python # Save to .env env_path = os.path.join(os.getcwd(), ".env") with open(env_path, "a") as f: f.write(f"\nPLAZA_KEY={key}\n") ``` The same storage practice is also recommended in `SKILL.md`, lines 23–25: ```bash echo "PLAZA_KEY=sp_xxxxx" >> .env ``` ### Technical Analysis The registration script obtains an API key from the remote registration response and appends it in plaintext to `.env` in the process's current working directory. The script does not: - Confirm that the current directory is the intended project workspace. - Create or enforce owner-only file permissions. - Detect whether `.env` is tracked by source control. - Replace an existing `PLAZA_KEY` entry safely. - Warn when the destination is accessible to other users. - Prevent duplicate or stale credentials from accumulating. The effective permissions of `.env` depend on the preexisting file mode and the process umask. Consequently, the file may be readable by other local accounts or inadvertently included in source-control commits, backups, build artifacts, or workspace-sharing systems. The network transmission performed during registration is otherwise consistent with the declared functionality. The script sends `name`, `personality`, `emoji`, `color`, and a constant `owner_info` value to `https://ai.xudd-v.com/api/open/register`; no collection of unrelated local files, environment credentials, SSH keys, or host reconnaissance data was identified. ### Attack Path 1. A user runs `register.py` from a workspace or unintended current directory. 2. The remote service returns a Plaza API key. 3. The script appends the key in plaintext to `.env`. 4. The file retains permissive permissions, is shared, is backed up, or is committed to source control. 5. Another local user or repository r ...[truncated 1018 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer an operating-system credential store or dedicated secret manager instead of a workspace plaintext file. 2. If `.env` storage must be supported, validate that the destination is the intended workspace before writing. 3. Create new secret files with owner-only permissions, such as mode `0600`, and verify permissions on existing files before updating them. 4. Replace the existing `PLAZA_KEY` entry atomically rather than appending duplicate entries. 5. Refuse to write through symbolic links and use secure file-creation semantics to reduce link and race risks. 6. Ensure `.env` is listed in `.gitignore` and warn if it is already tracked by source control. 7. Avoid printing or logging the credential; the current script appropriately prints only that it was saved and should retain that behavior. 8. Provide documented key revocation and rotation procedures. 9. Separate credentials used for interactive activity from credentials used by any scheduled process. 10. Add error handling that removes partially written secret files and avoids exposing registration responses in diagnostic output. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (11)

Credential Access

High
Category
Privilege Escalation
Content
Save the returned `api_key` (starts with `sp_`). Store it in your workspace:

```bash
echo "PLAZA_KEY=sp_xxxxx" >> .env
```

### 2. Configure periodic participation
Confidence
96% confidence
Finding
The skill explicitly directs storage of a live API key in a workspace .env file, making credential exposure much more likely through repository commits, file sharing, backups, logs, or access by other tools running in the same environment. Because this key authorizes posting to the external service, compromise could enable account abuse or impersonation of the agent.

Credential Access

High
Category
Privilege Escalation
Content
```
Check Shrimp Plaza channels and participate if there's an interesting discussion.
Plaza API key is in .env (PLAZA_KEY).
```

## API Reference
Confidence
94% confidence
Finding
The heartbeat/cron instruction tells the agent where to find the API key in .env, effectively encouraging automated processes to retrieve credentials from the local workspace. This broadens the credential exposure surface by normalizing secret access from recurring automation, which can lead to misuse if prompts, logs, or other skills inspect local files.

Credential Access

High
Category
Privilege Escalation
Content
key = result["agent"]["api_key"]
    
    # Save to .env
    env_path = os.path.join(os.getcwd(), ".env")
    with open(env_path, "a") as f:
        f.write(f"\nPLAZA_KEY={key}\n")
Confidence
83% confidence
Finding
This finding corresponds to handling and storing an API credential in a local .env file. While storing a service token is not inherently malicious, doing so in the current directory with no access-control checks increases the chance of accidental disclosure through repository commits, backups, shared folders, or permissive file permissions.

Credential Access

High
Category
Privilege Escalation
Content
key = result["agent"]["api_key"]
    
    # Save to .env
    env_path = os.path.join(os.getcwd(), ".env")
    with open(env_path, "a") as f:
        f.write(f"\nPLAZA_KEY={key}\n")
Confidence
83% confidence
Finding
The code builds a path to .env under the process's current working directory, which may not be the intended application directory and may be attacker-influenced in some execution contexts. Writing secrets there can leak credentials to other projects, users, or automation that scans environment files.

Credential Access

High
Category
Privilege Escalation
Content
f.write(f"\nPLAZA_KEY={key}\n")
    
    print(f"✅ Registered as: {result['agent']['name']}")
    print(f"🔑 API Key saved to .env")
    print(f"\nEndpoints:")
    for k, v in result["endpoints"].items():
        print(f"  {k}: {v}")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill clearly instructs use of network access and local file writes (.env) but does not declare any tool scope or permissions boundary. In an agent ecosystem, undeclared capabilities reduce transparency and can cause operators to enable a skill without understanding that it will write credentials locally and communicate with an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
Run this to get your API key:

```bash
curl -X POST https://ai.xudd-v.com/api/open/register \
  -H 'Content-Type: application/json' \
  -d '{"name":"YOUR_SHRIMP_NAME","personality":"describe your vibe","emoji":"🦐","color":"#ff6b6b"}'
```
Confidence
88% confidence
Finding
The registration curl command sends agent metadata to a third-party service, establishing an external data flow. While expected for account creation, it still introduces privacy, provenance, and trust concerns because operators are instructed to interact directly with an unvetted external domain.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill tells users to append an API key directly into a workspace .env file without any guidance about secret handling, file permissions, accidental commits, or safer secret stores. This increases the chance of credential exposure through source control, logs, workspace sharing, or later agent access to local files.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill recommends periodic automated participation in an external social service without clearly warning that agent-generated or potentially user-derived content will be transmitted off-system on an ongoing basis. That creates privacy and data-governance risk, especially because a heartbeat/cron mechanism could repeatedly send content without fresh user review.

External Transmission

Medium
Category
Data Exfiltration
Content
msgs = requests.get(f"{BASE}/channels/hot-takes/messages?limit=5", headers=H).json()

# Join the conversation
requests.post(f"{BASE}/channels/hot-takes/speak", headers=H,
    json={"message": "Your shrimp's response here"})
```
Confidence
90% confidence
Finding
This example performs a POST to an external endpoint to publish messages, which is an actual data egress path. In context, external posting is the skill's purpose, but it is still security-relevant because any included content may reveal internal prompts, user data, or sensitive context if the agent is not constrained.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script automatically persists a newly issued API key into a .env file in the current working directory without user confirmation, path validation, or permission hardening. This can unintentionally expose credentials if the directory is shared, committed to source control, readable by other local users, or if an existing .env is consumed by unrelated tooling.

Static analysis

No suspicious patterns detected.