Back to skill

Security audit

discord-cli

Security checks for vulnerabilities and agentic risk

Overview

This Discord CLI is mostly coherent, but it gives the agent sensitive Discord account-token access, stores that token insecurely, can bulk-cache Discord messages, and can send raw chat content to Anthropic without a clear per-use consent boundary.

Review carefully before installing. Use this only for Discord accounts and servers where you are allowed to automate access. Avoid `discord auth --save` unless you accept local session-token extraction and plaintext `.env` storage; prefer tightly controlled credentials and protect or remove any saved token. Avoid `sync-all` and broad summaries unless you intend to cache and process all accessible messages. Do not run AI summary or analysis on private or confidential channels unless participants and your organization permit sending that content to Anthropic.

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
src/discord_cli/auth.py:93
Finding

Discord User Token Stored in an Unprotected Plaintext .env File

Content
View full analysis
Path: """Save token to .env file.""" if env_path is None: env_path = Path.cwd() / ".env" lines = [] token_found = False if env_path.exists(): for line in env_path.read_text().splitlines(): if line.startswith("DISCORD_TOKEN="): lines.append(f"DISCORD_TOKEN={token}") token_found = True else: lines.append(line) if not token_found: lines.append(f"DISCORD_TOKEN={token}") env_path.write_text("\n".join(lines) + "\n") return env_path ``` The credential is obtained by scanning browser and Discord storage: ```python def find_tokens() -> list[dict]: """Scan known browser/Discord client paths for tokens. Returns list of {source, token} dicts, deduplicated by token. """ search_paths = _get_search_paths() found: dict[str, str] = {} # token -> source for source_name, db_path in search_paths: if not db_path.is_dir(): continue # Scan .ldb and .log files for ext in ("*.ldb", "*.log"): for filepath in db_path.glob(ext): for token in _extract_tokens_from_file(filepath): if token not in found: found[token] = source_name return [{"source": source, "token": token} for token, source in found.items()] ``` ### Technical Analysis The `auth` command deliberately searches multiple Discord and browser profiles for reusable Discord user tokens. When the user supplies `--save`, the selected token is written d ...[truncated 2242 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/discord_cli/analyzer.py:42
Finding

Raw Discord Messages and Sender Metadata Transmitted to Anthropic Without Explicit Disclosure or Confirmation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (52)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill appears able to retrieve detailed account and user profile information, list members, and enumerate guild metadata beyond the narrowly advertised use case. While some of this may support Discord workflows, under-disclosing access to personal/account data creates privacy and overcollection risks, especially when operated by an agent on the user's behalf.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill appears able to retrieve detailed account and user profile information, list members, and enumerate guild metadata beyond the narrowly advertised use case. While some of this may support Discord workflows, under-disclosing access to personal/account data creates privacy and overcollection risks, especially when operated by an agent on the user's behalf.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill appears able to retrieve detailed account and user profile information, list members, and enumerate guild metadata beyond the narrowly advertised use case. While some of this may support Discord workflows, under-disclosing access to personal/account data creates privacy and overcollection risks, especially when operated by an agent on the user's behalf.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill appears able to retrieve detailed account and user profile information, list members, and enumerate guild metadata beyond the narrowly advertised use case. While some of this may support Discord workflows, under-disclosing access to personal/account data creates privacy and overcollection risks, especially when operated by an agent on the user's behalf.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

AI analysis and summary features likely send message content to an external provider, but the skill does not provide a prominent privacy warning or consent boundary for that transmission. Because the tool handles chat history, this can expose sensitive or private Discord content to third parties unexpectedly.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file is explicitly designed to enumerate local browser and Discord client storage locations, regex-scan LevelDB/log data for Discord tokens, and return recovered credentials. That behavior goes well beyond a normal Discord CLI scope and constitutes credential harvesting from unrelated local applications, which can enable full account takeover.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code traverses known browser and Discord client data directories across macOS, Windows, and Linux, then extracts credential-like strings using token regexes. This is a classic local credential harvesting pattern and is especially dangerous because it targets sensitive auth material from multiple applications without a legitimate need established by the skill description.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The token extraction routine silently scans local LevelDB and log files for Discord credentials with no user-facing disclosure, consent prompt, or approval gate. Silent access to highly sensitive credentials is dangerous because users and calling agents may be unaware that the tool is harvesting authentication tokens from local applications.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

Writing a Discord token to .env without any warning or consent stores a powerful credential in plaintext on disk, where it may be exposed through source control, logs, backups, shell tooling, or other local processes. The absence of a user-facing warning makes accidental secret leakage much more likely.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

This finding points to the credential persistence entry point that defaults to creating or modifying a .env file in the current working directory. In context, it facilitates storage of a recovered Discord token, increasing the chance of credential disclosure through plaintext files and downstream tooling.

Content

Scanner excerpt · src/discord_cli/auth.py (reported line 94)May include surrounding context.

python
def save_token_to_env(token: str, env_path: Path | None = None) -> Path:
    """Save token to .env file."""
    if env_path is None:
        env_path = Path.cwd() / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
82% confidence
Finding

This line reflects the hardcoded default behavior of persisting secrets into a .env file, which is a weak storage location for bearer tokens. Because Discord tokens grant direct account access, plaintext persistence materially increases exposure if the working directory is shared, synced, or committed.

Content

Scanner excerpt · src/discord_cli/auth.py (reported line 96)May include surrounding context.

python
def save_token_to_env(token: str, env_path: Path | None = None) -> Path:
    """Save token to .env file."""
    if env_path is None:
        env_path = Path.cwd() / ".env"

    lines = []
    token_found = False

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The sync-all command discovers all accessible channels across guilds, fetches message history for each, and stores results locally at scale, but gives no clear warning about the breadth of collection or persistence. In this skill context, that materially increases risk because an agent can bulk-exfiltrate or quietly archive large volumes of cross-server communications, magnifying privacy, compliance, and insider-threat impact.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The auth command extracts Discord user tokens from local browser/Desktop sessions, validates them against Discord, and optionally saves a valid token to .env. This is credential harvesting/access behavior that is not disclosed by the skill metadata and is especially dangerous because Discord user tokens grant account access and may violate platform terms, enabling account takeover or unauthorized data access if misused.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The auth command is explicitly designed to extract a Discord token from local sessions and optionally persist it to .env, which is credential access and insecure credential handling. Storing a harvested account token in a local environment file can expose it to accidental commits, weak filesystem protections, other local processes, or later exfiltration, enabling unauthorized account access.

Content

Scanner excerpt · src/discord_cli/cli/main.py (reported line 42)May include surrounding context.

python
@cli.command("auth")
@click.option("--save", is_flag=True, help="Save found token to .env automatically")
def auth(save: bool):
    """Extract Discord token from local browser/Discord client."""
    import httpx

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

A chat/search CLI does not need to scan local browsers or the Discord client for authentication tokens; this is an unjustified credential-access capability. In this context, the mismatch between stated purpose and implemented behavior makes the feature more dangerous because an operator or downstream agent may invoke it without understanding that it is harvesting local session secrets.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

get_me returns highly sensitive account attributes including email and phone, which are not necessary for the declared Discord CLI use cases and increase the blast radius of any downstream logging, prompt injection, or exfiltration issue. In an AI-agent workflow, these fields may be surfaced to models, stored in traces, or emitted in structured output without the user's informed expectation.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/discord_cli/config.py (reported line 1)May include surrounding context.

python
"""Configuration management - loads from .env or environment variables."""

from __future__ import annotations

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/discord_cli/config.py (reported line 15)May include surrounding context.

python
"""Configuration management - loads from .env or environment variables."""

from __future__ import annotations

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/discord_cli/config.py (reported line 16)May include surrounding context.

python
def _load_env() -> None:
    """Load .env from cwd first, then fall back to the source checkout."""
    for candidate in (Path.cwd() / ".env", _PROJECT_ROOT / ".env"):
        if candidate.is_file():
            load_dotenv(candidate)
            return

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises commands that inherently use network access, local file reads/writes, and environment variables, but it declares no explicit tool scope or permissions boundary. In an agent setting, that omission increases the chance an orchestrator will run the skill with overly broad privileges and without informed user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

A destructive purge command is documented with a force-style flag but without a clear warning about irreversible local data loss. In agent workflows, terse command examples can be replayed automatically, making accidental deletion more likely.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest frames the tool as read-only Discord access, but the documented purge command performs destructive deletion of locally stored data. This mismatch can lead agents or users to invoke the skill under false assumptions, causing unintended data loss in environments that expected only non-destructive behavior.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
## Safety Notes

- Do not ask users to share raw token values in chat logs.
- Prefer auto-extraction via `discord auth --save` over manual token input.
- Token is stored locally and never uploaded.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The default prompt explicitly instructs the model with 请用中文回答, and the summary prompt also requires 用中文回答. This is a natural-language locale policy issue because the skill hard-codes a specific language rather than offering user choice or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This function sends full chat message content to Anthropic without any consent check, warning, redaction, or indication in this file that users understand their messages leave the local environment. If the messages contain private conversations, credentials, personal data, or confidential project information, the tool can cause unintended data disclosure to a third-party service.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.