Back to skill

Security audit

Discord Project Manager

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent with its Discord project-management purpose, but it handles sensitive OpenClaw/Discord credentials in ways that could expose tokens or alter central agent configuration.

Install only if you trust this skill with your OpenClaw configuration and Discord bot authority. Before use, back up ~/.openclaw/openclaw.json, avoid running diagnostic commands that print raw config, restrict the bot to the minimum Discord permissions and guilds needed, and review/fix the config-file permission preservation and token redaction issues.

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

Error
Location
lib/config.py:80
Finding

OpenClaw Configuration Permissions Are Not Preserved During Atomic Replacement

Content
View full analysis

Vulnerability Details

File Location: lib/config.py:80-104
Vulnerability Type: T09: Insecure Skill Coding Practices
Risk Level: High

Vulnerable Code

python
def _write_config_locked(self, config: Dict) -> str:
    """Write config with file locking and backup.
    
    Args:
        config: Config dict to write
        
    Returns:
        Backup file path
    """
    backup_path = f"{self.CONFIG_PATH}.bak-{int(time.time())}"
    shutil.copy(self.CONFIG_PATH, backup_path)
    
    lock_fd = open(self.LOCK_PATH, 'w')
    try:
        fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
        
        # Write to temp file then rename (atomic)
        tmp_path = f"{self.CONFIG_PATH}.tmp"
        with open(tmp_path, 'w') as f:
            json.dump(config, f, indent=2, ensure_ascii=False)
        os.replace(tmp_path, self.CONFIG_PATH)
        
    finally:
        fcntl.flock(lock_fd, fcntl.LOCK_UN)
        lock_fd.close()
    
    return backup_path

Technical Analysis

The temporary configuration file is created with Python's default open(..., 'w') behavior. Its permissions are consequently determined by the process umask instead of inheriting the restrictive permissions of the original ~/.openclaw/openclaw.json.

For example, under a common 022 umask, the temporary file may be created with mode 0644. The subsequent os.replace() operation replaces the original configuration inode with this newly created file, so a configuration previously protected with mode 0600 can become readable by other local users.

The OpenClaw configuration contains Discord bot tokens and may contain additional account credentials. This write path is reached by direct permission-removal operations and by the fallback configuration-patching path.

The lock also does not address the permission issue because it only coordinates cooperating writers; it does not control the ...[truncated 1477 chars]

Remediation
View remediation

Remediation Suggestions

  • Preserve the original configuration's owner, group, and mode when replacing it.
  • Create the temporary file explicitly with mode 0600, rather than relying on the current umask. For example, use os.open() with O_WRONLY | O_CREAT | O_EXCL and mode 0o600, then wrap the descriptor with os.fdopen().
  • Use a uniquely named temporary file in the same directory, such as one created through tempfile.mkstemp(dir=config_directory).
  • Call os.fchmod(fd, 0o600) defensively before writing sensitive data.
  • Flush and call os.fsync() on the temporary file before replacement, then fsync the parent directory after os.replace().
  • Acquire the lock before reading, copying, or modifying the configuration so the entire read-modify-write transaction is protected.
  • Verify after replacement that the resulting file has the expected owner and restrictive mode. Abort or correct the mode if it does not.
  • Apply equally restrictive permissions to the lock file and all timestamped backup files.

T09 · Insecure Skill Coding Practices

Warning
Location
lib/config.py:290
Finding

Diagnostic Commands Print Discord Bot Tokens in Plaintext

Content
View full analysis

Vulnerability Details

File Location: lib/config.py:290-297
Vulnerability Type: T09: Insecure Skill Coding Practices
Risk Level: Medium

Vulnerable Code

python
if command == 'get':
    result = config.get()
    print(json.dumps(result, indent=2, ensure_ascii=False))

elif command == 'accounts':
    accounts = config.get_discord_accounts()
    print(json.dumps(accounts, indent=2, ensure_ascii=False))

Technical Analysis

The get command serializes and prints the complete OpenClaw configuration. The accounts command prints the complete Discord account structures. Based on the token-loading implementation elsewhere in the project, these structures can contain credentials under fields such as:

text
channels.discord.accounts.*.token
channels.discord.token

Neither command performs recursive redaction or limits its output to non-sensitive metadata. Consequently, Discord bot tokens are written directly to standard output.

Standard output is frequently captured by terminal logging, CI/CD systems, orchestration services, support bundles, agent transcripts, or shell redirection. This behavior also conflicts with the statement in SKILL.md that the bot token is never logged.

Attack Path

  1. A user, support operator, automation task, or agent invokes lib/config.py get or lib/config.py accounts.
  2. The command loads the full configuration or Discord account configuration.
  3. The unredacted JSON, including any Discord token fields, is printed to standard output.
  4. Output is retained in a terminal transcript, CI log, monitoring system, redirected file, or agent conversation record.
  5. A person or service with access to that retained output obtains the bot token.
  6. The token is used to authenticate directly to Discord as the configured bot.

Impact Assessment

Exposure grants the observer the effective Discord identity and privileges of the affected bot unt ...[truncated 482 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not print the complete configuration or complete account objects by default.
  • Implement recursive redaction before serialization. At minimum, redact keys such as token, secret, password, apiKey, authorization, and private-key fields.
  • Replace sensitive values with a constant marker such as [REDACTED]; do not reveal prefixes or suffixes unless operationally necessary.
  • Make diagnostic output an explicit allowlist of safe fields, such as account identifiers, guild identifiers, and channel identifiers.
  • If raw output is absolutely required for a narrowly defined administrative workflow, require an explicit high-friction option, display a warning, write only to a securely created 0600 file, and avoid stdout.
  • Add automated tests containing synthetic token fields at multiple nesting levels and verify that no credential value appears in command output.
  • Update the documentation so its token-handling guarantees accurately reflect the implemented behavior.
  • Rotate any bot token that may already have been captured in logs or transcripts.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims collaboration management features but appears to perform agent-registry file management and read ~/.openclaw/openclaw.json without accurately reflecting that behavior. In this context, undeclared access to a central OpenClaw configuration file is especially dangerous because it may expose account mappings, tokens, and channel permissions, and any writes can alter agent communication policy across the environment.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims collaboration management features but appears to perform agent-registry file management and read ~/.openclaw/openclaw.json without accurately reflecting that behavior. In this context, undeclared access to a central OpenClaw configuration file is especially dangerous because it may expose account mappings, tokens, and channel permissions, and any writes can alter agent communication policy across the environment.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims collaboration management features but appears to perform agent-registry file management and read ~/.openclaw/openclaw.json without accurately reflecting that behavior. In this context, undeclared access to a central OpenClaw configuration file is especially dangerous because it may expose account mappings, tokens, and channel permissions, and any writes can alter agent communication policy across the environment.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims collaboration management features but appears to perform agent-registry file management and read ~/.openclaw/openclaw.json without accurately reflecting that behavior. In this context, undeclared access to a central OpenClaw configuration file is especially dangerous because it may expose account mappings, tokens, and channel permissions, and any writes can alter agent communication policy across the environment.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill claims collaboration management features but appears to perform agent-registry file management and read ~/.openclaw/openclaw.json without accurately reflecting that behavior. In this context, undeclared access to a central OpenClaw configuration file is especially dangerous because it may expose account mappings, tokens, and channel permissions, and any writes can alter agent communication policy across the environment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Host process discovery and signaling capability is unjustified by the declared skill purpose and materially increases risk. In the context of an agent skill, such capability can be repurposed for denial of service, interference with other workloads, or persistence-related runtime manipulation if the skill is invoked by a compromised agent or prompt flow.

Content

No source excerpt is available for this finding.

Context Leakage

High
Category
Data Exfiltration
Confidence
91% confidence
Finding

The code raises an exception that includes the full raw thread_result object when the expected thread ID is missing. If that API response contains sensitive metadata, tokens, internal identifiers, or unexpected message content, it may be exposed through logs, CLI output, or upstream error handling. In a Discord project-management skill that coordinates multiple agents and permissions, leaking raw integration responses increases the chance of cross-context data disclosure.

Content

Scanner excerpt · lib/thread.py (reported line 82)May include surrounding context.

python
forum_id, name, message
        )
        
        # Extract thread ID from response
        thread_id = thread_result.get('payload', {}).get('thread', {}).get('id')
        if not thread_id:
            raise ValueError(f"Failed to create thread: no thread id in response. Got: {thread_result}")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill exposes capabilities for file read/write, shell/process control, and network access, but does not declare an explicit tool scope such as allowed tools. That weakens reviewability and enforcement, because consumers may trust the markdown description while the skill can modify local config, restart services, and interact with Discord over the network.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation claims all config changes go through openclaw config.patch, but the implementation also directly edits config files and may restart the gateway. This mismatch is security-relevant because reviewers and operators may underestimate the skill's actual privileges and side effects, leading to unsafe deployment decisions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The helper includes broad gateway/process management logic in a skill described as Discord collaboration infrastructure. This scope expansion increases blast radius: a feature intended to manage channel permissions can also alter host configuration state and influence service lifecycle behavior.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
93% confidence
Finding

Although this is not shell injection, the subprocess is used for host process discovery via pgrep -f, followed by signaling matching PIDs. Pattern-based process discovery and subsequent signaling can affect unintended processes and grants this skill capability to enumerate and control host processes beyond Discord channel management.

Content

Scanner excerpt · lib/config.py (reported line 56)May include surrounding context.

python
['pgrep', '-f', 'openclaw.*gateway'],
            ]
            for cmd in patterns:
                result = subprocess.run(
                    cmd, capture_output=True, text=True, timeout=5
                )
                if result.returncode == 0 and result.stdout.strip():

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
84% confidence
Finding

This code can invoke openclaw gateway restart, which gives the skill direct host-level process control outside its stated Discord project-management purpose. If an untrusted or over-privileged caller can trigger this path, they can cause service disruption or manipulate the agent runtime by restarting the gateway.

Content

Scanner excerpt · lib/config.py (reported line 69)May include surrounding context.

python
# Last resort: openclaw gateway restart
        try:
            result = subprocess.run(
                ['openclaw', 'gateway', 'restart'],
                capture_output=True, text=True, timeout=15
            )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · lib/config.py (reported line 129)May include surrounding context.

python
"""
        patch_json = json.dumps(patch)
        
        result = subprocess.run(
            ['openclaw', 'config.patch', '--raw', patch_json, '--note', note],
            capture_output=True,
            text=True,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill reads a Discord bot token from the local OpenClaw configuration without requiring explicit user consent at the point of use. Accessing local credentials expands the skill's privilege boundary and enables authenticated remote actions as the bot, which is more sensitive than a generic project-management helper needs unless clearly disclosed and scoped.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Silently loading a Discord bot token from local configuration is a security-relevant side effect because it consumes stored credentials without notifying the user. In this skill context, that makes the agent capable of authenticated Discord operations under the user's environment, increasing the blast radius if the skill is invoked unexpectedly or abused.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This function performs outbound authenticated API calls that create Discord channels, causing persistent remote side effects without any visible warning or confirmation mechanism. Because the skill is for project coordination, channel creation is contextually related, but automatic remote mutation still warrants disclosure and approval to prevent accidental or unauthorized changes.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · lib/discord_api.py (reported line 130)May include surrounding context.

python
cmd.extend(['-m', message])
        
        try:
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill sends messages to Discord via an external CLI without warning the user that provided content will be transmitted off-host and posted remotely. In a multi-agent collaboration setting, this can leak sensitive prompts, internal data, or unintended content if invocation is implicit or manipulated.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · lib/discord_api.py (reported line 166)May include surrounding context.

python
]
        
        try:
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
76% confidence
Finding

The create operation transmits guild and channel metadata to Discord via a REST API call. While the function name implies creation, the surrounding CLI help and docstrings do not explicitly warn users that invoking this command performs a live network action against Discord.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code writes to the registry as a side effect of creating a forum channel, and similar save operations recur elsewhere in the file. Although there are status prints after the fact, there is no confirmation prompt or explicit warning that local configuration/registry data will be modified before the write occurs.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The manifest presents the skill as Discord project-management infrastructure, but these methods invoke an external command-line tool via subprocess to create threads and send messages. Launching subprocesses is a broader host-execution capability that is not implied by the manifest's functional description and is sensitive from an intent-auditing perspective.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The skill is described as Discord project collaboration infrastructure managing channels, threads, permissions, and mention mode. This file additionally reaches into a user-scoped OpenClaw config at ~/.openclaw/openclaw.json to derive settings, which is a local file access capability not implied by the manifest's Discord-management purpose.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.