Back to skill

Security audit

agent-council

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it needs Review because it can change Discord/OpenClaw/workspace state, create persistent agents, and includes unsafe command/config generation.

Install only if you intend to let this skill administer Discord channels and OpenClaw agents. Review generated commands before running them, avoid untrusted channel names/context/system prompts, use a narrow workspace path, keep the workspace under version control, and do not enable the memory cron unless you want persistent autonomous file writes.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup_channel.py:173
Finding

Shell Command Injection Through Printed Gateway Configuration Command

Content
View full analysis
Dict[str, Any]: """Build gateway config patch for the channel.""" return { "channels": { "discord": { "guilds": { guild_id: { "channels": { channel_id: { "allow": True, "requireMention": False, "systemPrompt": context } } } } } } } ``` ```python print(f"\nopenclaw gateway config.patch --raw '{json.dumps(patch)}'") ``` ### Technical Analysis The user-controlled `--context` value is inserted into a JSON object and then printed inside a single-quoted shell argument. JSON encoding does not escape characters according to shell quoting rules. In particular, an apostrophe in `context` remains capable of terminating the shell's single-quoted argument. Although the script does not execute the generated command itself, its documented workflow explicitly instructs the operator to copy and execute that command. A crafted context can therefore append arbitrary shell syntax to the displayed command. ### Attack Path 1. An attacker supplies or recommends a crafted `--context` value containing an apostrophe followed by shell metacharacters and an attacker-selected command. 2. The script incorporates that value into `systemPrompt`. 3. The script prints the resulting JSON inside a single-quoted `openclaw gateway config.patch` command. 4. The operator follows the documented workflow and executes the printed command. 5. The injected shell command run ...[truncated 615 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/rename_channel.py:165
Finding

Shell Command Injection Through Existing Discord System Prompt

Content
View full analysis
Dict[str, Any]: """Build gateway config patch to update systemPrompt.""" new_prompt = old_prompt.replace(old_name, new_name) return { "channels": { "discord": { "guilds": { guild_id: { "channels": { channel_id: { "systemPrompt": new_prompt } } } } } } } ``` ```python if old_prompt: print(f"\n⚠️ systemPrompt contains '{old_name}' - needs updating") patch = build_system_prompt_patch(guild_id, channel_id, old_prompt, old_name, new_name) print(f"\n📝 Run this command to update systemPrompt:") print(f"\nopenclaw gateway config.patch --raw '{json.dumps(patch)}'") ``` ### Technical Analysis The script reads an existing `systemPrompt` from the OpenClaw configuration, modifies it, serializes it as JSON, and places it inside a single-quoted shell command. JSON serialization does not make a value safe for embedding in shell syntax. An apostrophe or other crafted shell content already present in the system prompt can terminate the quoted argument when the displayed command is copied into a shell. The replacement operation does not sanitize the resulting prompt. ### Attack Path 1. An attacker gains the ability to influence a channel's existing `systemPrompt`, or convinces an operator to use a prompt containing crafted shell content. 2. The prompt also contains the old channel name, causing the update branch to execute. 3. The operator runs `renam ...[truncated 575 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create-agent.sh:209
Finding

Gateway Configuration Injection Through Manual JSON Construction

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/rename_channel.py:76
Finding

Unbounded Recursive Markdown Rewrites and Symlink-Following File Modification

Content
View full analysis
List[str]: """Search and update workspace files with new channel name.""" updated_files = [] # Patterns to replace patterns = [ (f"#{old_name}", f"#{new_name}"), # Channel mentions (f'"{old_name}"', f'"{new_name}"'), # Quoted references (f"/{old_name}/", f"/{new_name}/"), # Path-like references ] # Search all markdown files for md_file in workspace.rglob("*.md"): if md_file.is_file(): content = md_file.read_text() original_content = content # Apply all patterns for old_pattern, new_pattern in patterns: content = content.replace(old_pattern, new_pattern) # Write back if changed if content != original_content: md_file.write_text(content) updated_files.append(str(md_file.relative_to(workspace))) return updated_files ``` ### Technical Analysis When `--workspace` or `OPENCLAW_WORKSPACE` is provided, the script recursively rewrites every Markdown file beneath that path. It does not: - Restrict updates to known OpenClaw files. - Present a dry-run diff or request confirmation. - Reject symbolic links. - Verify that resolved targets remain inside the selected workspace. - Create backups. - Use atomic file replacement. - Handle encoding and partial-write failures. A Markdown symlink can satisfy `is_file()`, while `read_text()` and `write_text()` operate on its target. This can modify a Markdown file outside the intended workspace if the operator has permission. Even without symlinks, selecting an overly broad works ...[truncated 1042 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (13)

Instruction Override

High
Category
Prompt Injection
Confidence
70% confidence
Finding

This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 304)May include surrounding context.

md
### Finding Discord IDs

**Enable Developer Mode:**
- Settings → Advanced → Developer Mode

**Copy IDs:**

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

Scanner excerpt · SKILL.md (reported line 436)May include surrounding context.

})

text

### Send Messages to Agents

**Direct communication:**
```typescript

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

Scanner excerpt · SKILL.md (reported line 516)May include surrounding context.

text

**4. Agent-to-agent communication:**
Agents can send messages to each other:
```typescript
// In Watson's context
sessions_send({

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · SKILL.md (reported line 683)May include surrounding context.

md
1. **Organize channels in categories** - Group related agent channels
2. **Use descriptive channel names** - Clear purpose from the name
3. **Set specific system prompts** - Give each channel clear context
4. **Document agent responsibilities** - Keep SOUL.md updated
5. **Set up memory cron jobs** - For agents with ongoing work
6. **Test agents individually** - Before integrating into team

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/rename_channel.py (reported line 109)May include surrounding context.

python
try:
        prompt = config['channels']['discord']['guilds'][guild_id]['channels'][channel_id].get('systemPrompt', '')
        if old_name in prompt:
            return prompt
    except (KeyError, TypeError):
        pass
    return None

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill's 'use when' description is broad enough to activate on many common multi-agent or Discord-management requests, increasing the chance the agent will invoke automation that creates agents, edits gateway configuration, or modifies Discord state without sufficiently narrow user intent checks. In a skill that can change external systems and workspace files, overbroad routing materially raises the risk of unintended side effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation advertises creating Discord channels, updating gateway allowlists, renaming channels, and searching/updating workspace files, but it does not prominently require user confirmation or warn that these are external and filesystem-modifying actions. This can cause an agent to treat administrative changes as routine, leading to unintended infrastructure and data modifications.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 73)May include surrounding context.

md
- **Emoji** (e.g., "🔬")
- **Specialty** (what the agent does)
- **Model** (which LLM to use)
- **Workspace** (where to create agent files)
- **Discord channel ID** (optional)

#### 2. Run Creation Script

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 321)May include surrounding context.

md
- **Emoji** (e.g., "🔬")
- **Specialty** (what the agent does)
- **Model** (which LLM to use)
- **Workspace** (where to create agent files)
- **Discord channel ID** (optional)

#### 2. Run Creation Script

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

This script sets up optional scheduled persistence by creating a recurring cron task tied to an agent session. Persistent autonomous execution expands the attack surface because a compromised or misdirected agent can continue operating and modifying state over time without a fresh approval for each run.

Content

Scanner excerpt · scripts/create-agent.sh (reported line 294)May include surrounding context.

sh
echo -e "${YELLOW}📅 Memory System${NC}"
echo ""
echo "Would you like to set up a daily memory cron job for $NAME?"
echo "This will create a job that reviews and updates the agent's daily memory file."
echo ""
read -p "Create daily memory cron? (y/n): " -n 1 -r
echo ""

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script offers to create a cron job that later performs autonomous file writes to the agent's memory directory and explicitly instructs the agent to reply silently with HEARTBEAT_OK. Even though the user consents at setup time, the runtime behavior is non-interactive and can mask ongoing persistence, unexpected data growth, or prompt-influenced content being written without contemporaneous user visibility.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script writes updated content directly back to each matching markdown file with md_file.write_text(content). Although it later prints which files were changed, there is no confirmation prompt before the write and no warning in the docstring or CLI help that running with --workspace will edit files in place.

Content

No source excerpt is available for this finding.

Excessive Permissions

Low
Category
Privilege Escalation
Confidence
80% confidence
Finding

Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.

Content

Scanner excerpt · SKILL.md (reported line 691)May include surrounding context.

md
## Requirements

**Bot Permissions:**
- `Manage Channels` - To create/rename channels
- `View Channels` - To read channel list
- `Send Messages` - To post in channels

Static analysis

No suspicious patterns detected.