Back to skill

Security audit

Discord Admin

Security checks for vulnerabilities and agentic risk

Overview

The skill openly provides Discord administration, but it exposes webhook secrets and performs destructive server actions without its own confirmation guardrails.

Install only after reviewing whether you need this full administration surface. Use a dedicated Discord bot with the smallest permissions possible, restrict it to intended servers, avoid exposing tool outputs to untrusted users, rotate any webhook URLs that may be revealed, and require human confirmation before bans, deletes, role changes, channel permission changes, or webhook/invite deletion.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
index.ts:925
Finding
Discord Webhook Credentials Exposed in Tool Responses## Vulnerability Details **File Location**: `index.ts`, lines 925–933 **Vulnerability Type**: Sensitive credential exposure **Risk Level**: High ### Vulnerable Code ```ts webhooks: hooks.map((hook: any) => ({ id: hook.id, name: hook.name, channelId: hook.channelId, url: hook.url, })), ``` The guild-level `webhook-list` branch immediately following this code returns the same sensitive `hook.url` property. ### Technical Analysis Discord webhook URLs contain an identifier and secret token that authorize unauthenticated webhook operations. They must therefore be treated as credentials rather than ordinary resource metadata. The `webhook-list` action serializes each complete webhook URL into the tool response. The shared `json()` response helper places the data in both textual tool content and the `details` field. This can expose the credential to the language model context, conversation history, tool telemetry, application logs, or downstream integrations. Listing webhooks only requires non-secret metadata such as the webhook ID, name, and channel ID. Returning the credential-bearing URL exceeds the minimum data exposure necessary for the declared listing functionality. ### Attack Path 1. An attacker, untrusted prompt, or compromised workflow induces the agent to invoke `discord_admin` with the `webhook-list` action. 2. The plugin retrieves the channel or guild webhooks using the privileged Discord bot. 3. The plugin returns each complete `hook.url` in the tool response. 4. The attacker obtains the response through agent output, logs, telemetry, or another consumer of tool results. 5. The attacker extracts the webhook token from the URL. 6. The attacker submits requests directly to the Discord webhook without possessing the bot token. 7. The webhook remains usable until it is deleted or its token is rotated. ### Impact Assessment Exposure grants the ability to authenticate as each disclosed web ...[truncated 353 chars]
Remediation
## Remediation Suggestions - Remove `url` from all `webhook-list` responses. - Return only non-secret metadata such as `id`, `name`, `channelId`, and webhook type. - Treat Discord webhook URLs as credentials in logging and redaction policies. - If URL disclosure is genuinely required, implement a separate operation requiring explicit authorization and confirmation. - Prevent credential-bearing responses from being written to ordinary logs or telemetry. - Rotate or recreate any webhooks whose URLs may already have been exposed through tool history. - Add automated tests asserting that webhook list responses never contain token-bearing URLs.

T09 · Insecure Skill Coding Practices

Error
Location
index.ts:494
Finding
Destructive Discord Administration Actions Lack Explicit Confirmation Controls## Vulnerability Details **File Location**: `index.ts`, line 494 **Vulnerability Type**: Unsafe execution of destructive privileged operations **Risk Level**: High ### Vulnerable Code ```ts // TODO(security): require an explicit confirmation token for destructive actions. ``` This comment appears immediately before the action dispatcher. The handlers subsequently execute destructive operations directly, including role deletion, member bans, bulk message deletion, channel permission changes, invite deletion, and webhook deletion. For example, the role deletion handler performs the operation immediately after resolving the supplied identifiers: ```ts case "role-delete": return withActionResult(async () => { const client = requireClient(api); const input = params as { guildId: string; roleId: string }; const guild = await requireGuild(client, input.guildId); const role = await guild.roles.fetch(input.roleId); if (!role) throw new Error(`Role not found: ${input.roleId}`); await role.delete(); return { action, guildId: guild.id, roleId: input.roleId, deleted: true }; }); ``` ### Technical Analysis The tool exposes high-impact administrative operations through a single action parameter and executes them after one tool invocation. There is no short-lived confirmation token, dry-run phase, action allowlist, guild allowlist, or independent approval requirement. Discord's own permission checks constrain what the bot account can do, but they do not protect against an erroneous, prompt-influenced, or unauthorized agent invocation when the bot already has the required permissions. The source explicitly acknowledges the missing control through its security TODO. Because the Skill is intended for administration, the underlying Discord permissions are functionally necessary. However, exposing both read-only and irreversible operations through the same unrestricted tool unnecessarily incre ...[truncated 1267 chars]
Remediation
## Remediation Suggestions - Divide read-only and mutating functionality into separate tools with distinct authorization policies. - Require a short-lived confirmation token for destructive actions. - Bind confirmation tokens to the exact action, guild, target identifiers, and parameters so they cannot be reused for another operation. - Present a dry-run summary before execution, including the guild, target resource, and expected consequences. - Add configurable guild and action allowlists. - Require stronger approval for high-impact operations such as bans, role deletion, bulk deletion, and permission changes. - Record tamper-resistant audit events for destructive requests and their initiators. - Apply rate limits and bulk-operation ceilings to reduce damage from repeated calls. - Continue relying on Discord permission checks, but configure the bot with only the permissions needed for enabled actions rather than full administrator access.

T08 · Insecure Dependencies

Warning
Location
package.json:6
Finding
Non-Reproducible Dependency Installation Uses Broad Version Ranges## Vulnerability Details **File Location**: `package.json`, lines 6–9 **Vulnerability Type**: Dependency and supply-chain hardening weakness **Risk Level**: Medium ### Vulnerable Code ```json "dependencies": { "@sinclair/typebox": "^0.34.31", "discord.js": "^14" }, ``` Installation is performed with an unconstrained npm install step: ```text npm install ``` This instruction appears in `SKILL.md` at line 33 and is also declared in `openclaw.plugin.json` at line 28. No lockfile was present in the audited project structure. ### Technical Analysis The caret ranges permit future compatible releases to be selected during installation. In particular, `"discord.js": "^14"` allows dependency resolution to change substantially within the major version. Without a committed lockfile, different installations may receive different direct and transitive dependency versions. The installation process can also execute package lifecycle scripts under the privileges of the OpenClaw installation environment. A compromised dependency or unsafe future release could therefore introduce behavior that was not part of the reviewed source. This audit did not establish that either named dependency is malicious. The issue is the absence of deterministic dependency resolution and supply-chain controls. ### Attack Path 1. A direct or transitive dependency publishes a compromised version that satisfies the declared semver range, or its package distribution account is compromised. 2. A user follows the documented `npm install` procedure. 3. npm resolves the newly published version because no audited lockfile fixes the dependency graph. 4. Malicious lifecycle or runtime code executes in the plugin environment. 5. Such code may access process resources available to the plugin, potentially including the Discord bot token and network connectivity. 6. The compromised dependency can misuse Discord privileges or transmit accessible data ...[truncated 490 chars]
Remediation
## Remediation Suggestions - Commit a reviewed package lockfile to make direct and transitive dependency resolution deterministic. - Replace the documented `npm install` process with `npm ci` for production installation. - Pin exact reviewed dependency versions where operationally practical. - Use automated dependency scanning and update review procedures. - Verify package provenance, integrity metadata, and publisher ownership before upgrades. - Consider installing with lifecycle scripts disabled where compatible, and explicitly review any required scripts. - Run the plugin in an isolated process with minimal filesystem access and network egress restricted to required Discord endpoints. - Reassess dependency changes before distributing each Skill release.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (10)

Missing User Warnings

High
Confidence
98% confidence
Finding
The tool exposes many destructive administrative actions—ban, kick, delete, role deletion, channel permission changes, webhook deletion, invite deletion—without any confirmation, approval, or safety interlock, and the code even notes this missing control in a TODO. In an agent setting, prompt injection, misunderstanding, or accidental invocation could immediately cause irreversible moderation and configuration changes.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The webhook-list action enumerates existing webhooks and returns each hook.url, disclosing active posting credentials for all listed webhooks. This is especially dangerous because it turns a read/list operation into mass secret exfiltration, enabling unauthorized message injection across channels long after the tool call completes.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises network-capable administrative functionality but does not declare any explicit tool scope such as permissions or allowed-tools. In a plugin that can perform broad Discord moderation and server administration actions, this lack of scoping increases the chance of overbroad invocation and weakens policy enforcement around what the skill is allowed to access.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The warn action fetches an arbitrary user, opens a DM channel, and sends a message directly to that user. While the skill is framed as server administration, this introduces a separate outbound messaging capability that can be abused for harassment, phishing, or unauthorized contact outside the visible guild context.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The webhook-create action returns webhook.url, which is effectively a bearer secret that allows anyone with the URL to post messages into the channel. Exposing that URL through tool output expands access beyond Discord role permissions and can enable persistent spoofed posting if the output is logged, cached, or shown to unintended parties.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The server-info, audit-log, and member-list related functionality returns potentially sensitive operational and member data, including audit log executor/target IDs, member identities, join times, and server metadata, without any minimization or privacy disclosure. In an agent-accessible tool, this can enable unnecessary enumeration of users and moderation history beyond what the requester may need.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The plugin description claims a broad 'full Discord server administration suite' and the manifest requests extensive privileged capabilities, but it does not define any activation constraints, scope limitations, or task boundaries. In an agent ecosystem, this increases the chance the skill is invoked for loosely related prompts and can perform high-impact actions such as bans, role changes, webhook management, and audit log access without clear guardrails.

Excessive Permissions

Low
Category
Privilege Escalation
Content
This plugin requires a **Discord bot token** (`channels.discord.token` in OpenClaw config). The token is used exclusively to connect to the Discord gateway — it is never transmitted to any other endpoint.

**Required bot permissions:** Manage Roles, Kick Members, Ban Members, Moderate Members, Manage Channels, Manage Messages, Create Instant Invite, Manage Webhooks, View Audit Log, Manage Nicknames.

**Required privileged intents:** Guild Members (for member listing, kicks, timeouts, nickname changes).
Confidence
82% confidence
Finding
The skill requires a powerful Discord bot token with broad moderation, channel, invite, webhook, audit-log, and member-management privileges, including privileged intents. While these permissions are consistent with the stated purpose, compromise or misuse of the skill would enable substantial control over a Discord server, making the blast radius significant.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"type": "module",
  "main": "index.ts",
  "dependencies": {
    "@sinclair/typebox": "^0.34.31",
    "discord.js": "^14"
  },
  "openclaw": {
Confidence
90% confidence
Finding
The dependency uses a caret version range, which allows automatic installation of newer minor or patch releases instead of a single vetted version. In a privileged Discord administration skill, this increases supply-chain risk because a compromised or breaking upstream release could be pulled in and gain access to sensitive bot capabilities.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"main": "index.ts",
  "dependencies": {
    "@sinclair/typebox": "^0.34.31",
    "discord.js": "^14"
  },
  "openclaw": {
    "extensions": ["./index.ts"]
Confidence
96% confidence
Finding
The discord.js dependency is unpinned and specified as a broad major-version range, allowing different installs to resolve to different upstream releases. Because this skill performs full Discord server administration, any malicious or compromised dependency update could directly affect moderation, role, webhook, invite, and member-management functions, making the supply-chain exposure more dangerous than in a low-privilege package.

Static analysis

No suspicious patterns detected.