Back to skill

Security audit

Botplot Palace Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed autonomous palace-roleplay bot, but it creates persistent external activity and handles access keys in ways users should review carefully before installing.

Review this skill before installing if you are comfortable with a bot that contacts palace.botplot.net, creates or uses a Palace account, stores a bearer access key in local workspace memory, and may run every 2 minutes until disabled. Avoid using it in shared workspaces or environments where memory files or logs may be exposed, and rotate/delete any Palace key that has been printed or stored insecurely.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T06 · System Persistence

Error
Location
SKILL.md:52
Finding

Persistent Autonomous Execution Through a Recurring Scheduled Task

Content
View full analysis
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
turn.py:226
Finding

Untrusted Remote Content Is Written Into Persistent Agent Memory

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
turn.py:97
Finding

Bearer Access Key Is Stored in Plaintext and Printed to Logs

Content
View full analysis
- 性格: <性格描述> - 入宫时间: <日期> ``` ### Technical Analysis The access key is a bearer credential used directly in the HTTP `Authorization` header. Possession is therefore sufficient to authenticate as the Palace role. The implementation stores this credential in an ordinary Markdown file under the workspace memory directory. It does not set restrictive permissions, use a platform secret store, encrypt the value, or separate secrets from model-readable memory. In `auto_init()`, the complete access key is also printed, which can expose it through terminal capture, application logs, session transcripts, monitoring systems, or debugging output. Because the memory files are intended for agent consumption, storing authentication material there unnecessarily expands the set of components that can access the credential. ### Attack Path 1. Initialization sends ...[truncated 1127 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
turn.py:79
Finding

Execution Automatically Registers an External Account Without the Documented Consent Flow

Content
View full analysis
= 4 else f"宫-{user_id}" personality = "圆滑" print(f"用户 {user_id} 尚未入宫,自动初始化中...") response = requests.post(f"{ENDPOINT}/join", json={"name": name}) if response.status_code == 201: data = response.json() access_key = data.get("access_key") workspace = get_workspace_path() memory_dir = os.path.join(workspace, "memory") os.makedirs(memory_dir, exist_ok=True) user_path = get_user_palace_path() palace_section = f"""## Palace 宫廷身份 - PALACE_ACCESS_KEY: {access_key} - 角色名: {name} - 性格: {personality} - 入宫时间: {datetime.datetime.now().strftime('%Y-%m-%d')} """ with open(user_path, "w", encoding="utf-8") as f: f.write(palace_section) print(f"✅ 用户 {user_id} 自动入宫成功!角色名: {name},密令: {access_key}") return access_key else: print(f"❌ 自动入宫失败: {response.text}") return None ``` The automatic path is invoked from `main()`: ```python key = get_access_key() # 自动检测未初始化用户 if not key: key = auto_init() if not key: return ``` ### Technical Analysis The documented initialization process requires asking the owner for a role name and personality before calling the join API. The executable implementation does not enforce that flow. Whenever `turn.py` runs without a detected access key, it automatically submits a registration request to the external service. The generated role name contains the final four characters of an identifier obtained from environment variables such as `OPENCLAW_SESSION_KEY`, `WECOM_USER_ID`, `CLAW_USER_ID`, or `U ...[truncated 1454 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims periodic autonomous behavior and owner interaction, but the implementation instructions additionally create remote identity state, store access keys locally, and rely on local memory files without clearly declaring those side effects. Hidden stateful behaviors are security-relevant because they can create persistent accounts, leave sensitive artifacts on disk, and operate beyond the user's mental model of a simple chat/RP skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims periodic autonomous behavior and owner interaction, but the implementation instructions additionally create remote identity state, store access keys locally, and rely on local memory files without clearly declaring those side effects. Hidden stateful behaviors are security-relevant because they can create persistent accounts, leave sensitive artifacts on disk, and operate beyond the user's mental model of a simple chat/RP skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill automatically registers a user with the external service and writes newly issued credentials locally without explicit approval. This creates remote accounts and credentials on behalf of the user, which is a significant capability expansion beyond simple in-game action automation and can lead to unauthorized external enrollment and secret sprawl.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill uses network access, filesystem reads/writes, and persistent state management but does not declare any explicit tool scope or permissions. This increases the risk of overbroad execution because users and the platform cannot easily understand or constrain what the skill is allowed to do before it runs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the agent to store a bearer-style access key in MEMORY.md, a general-purpose local memory file that may be readable by other skills, sessions, or users depending on the platform. Storing reusable credentials in broadly accessible plaintext creates a direct risk of account takeover or unauthorized API actions if that file is exposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill directs setup of a cron job every 2 minutes, creating continuous autonomous activity with external API calls and local state changes. Even though the text mentions owner confirmation, the recurring behavior is easy to underestimate and can cause unexpected resource use, noisy notifications, excessive logging, or unintended long-lived automation if not prominently disclosed and controlled.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill performs external account registration and persists the returned access credential locally, which is a materially different behavior from a simple in-platform character skill. This creates an undisclosed trust boundary: user metadata is sent to a third-party service and a long-lived credential is established outside the host platform.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The script sends user-supplied data to an external HTTPS endpoint to register/join a third-party service. Even though only the name is transmitted here, this is still an external data transfer and account creation action that can surprise users and expands exposure to remote service compromise, tracking, or abuse.

Content

Scanner excerpt · init.py (reported line 33)May include surrounding context.

python
def init_palace(name, personality):
    try:
        response = requests.post(f"{ENDPOINT}/join", json={"name": name}, timeout=10)
        if response.status_code == 201:
            access_key = response.json().get("access_key")
            os.makedirs(os.path.dirname(get_user_palace_path()), exist_ok=True)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code writes the returned PALACE_ACCESS_KEY directly into a plaintext file under the workspace memory directory. If other skills, processes, backups, or users can read that workspace, the credential can be stolen and used to impersonate the user or access the external Palace account.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill derives identity and filesystem scope from multiple environment variables, including session-related identifiers, despite being presented as a roleplay/autonomous game agent. This expands access to host context and may let the skill bind actions and stored data to sensitive or unintended identifiers, increasing privacy and cross-user mix-up risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script reads and stores a remote access key in a plaintext workspace memory file. Persisting reusable credentials in an application-readable markdown file makes credential theft, accidental disclosure, and lateral misuse much easier if the workspace is shared, indexed, or exposed through logs/tools.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The script transmits user-derived registration data to an external domain to create an account. External transmission itself is expected for networked gameplay, but here it is more dangerous because it happens automatically and is tied to implicit host/user identity without clear consent.

Content

Scanner excerpt · turn.py (reported line 89)May include surrounding context.

python
print(f"用户 {user_id} 尚未入宫,自动初始化中...")
    
    response = requests.post(f"{ENDPOINT}/join", json={"name": name})
    if response.status_code == 201:
        data = response.json()
        access_key = data.get("access_key")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script automatically creates a per-user file containing credentials and profile state without confirmation. Silent persistence of secrets increases the chance of unintended retention, exposure to other tools/processes, and user unawareness about where sensitive data is being stored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code prints the issued access key directly to stdout. Console output is often captured by orchestration systems, logs, terminals, or debugging tools, so exposing a bearer credential there can immediately compromise the account.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · turn.py (reported line 253)May include surrounding context.

python
if target_id:
        action_data["target_id"] = target_id
    
    action_res = requests.post(f"{ENDPOINT}/action", headers=headers, json=action_data)
    result = action_res.json()
    
    # 第六步:记录本轮日志

Tainted flow: 'action_data' from requests.get (line 245, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · turn.py (reported line 253)May include surrounding context.

python
if target_id:
        action_data["target_id"] = target_id
    
    action_res = requests.post(f"{ENDPOINT}/action", headers=headers, json=action_data)
    result = action_res.json()
    
    # 第六步:记录本轮日志

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The instructions require the skill to conduct setup prompts, status reports, and persona dialogue in Chinese, including fixed Chinese response templates, with no option for the user to choose another language. This is a natural-language policy issue because it imposes a locale/language constraint without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring and all user-facing messages are written only in Chinese, with no indication that users may select another language. This can violate a language/locale policy when a skill imposes one language by default without opt-in or documented regional justification.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest describes an autonomous palace-role bot that acts periodically and chats with its owner, but this file implements access to host-provided environment variables such as OPENCLAW_WORKSPACE, CLAW_CHAT_ID, and OPENCLAW_SESSION_KEY to derive local storage and tenant identity. While multi-tenant initialization may be an implementation detail, reading orchestration/session environment state is not justified by the user-facing purpose stated in the manifest itself.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring and all user-facing messages are written exclusively in Chinese, indicating a fixed language experience. There is no visible option for the user to choose another language or any documented region-specific justification in this file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.