Back to skill

Security audit

Channel Bridge

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent message-routing library, but its documented filters can fail open and route messages more broadly than users configured.

Install only if you are comfortable reviewing and controlling every route yourself. Do not use this for confidential, regulated, or private channels until filters are fixed to fail closed, advertised channel filters are actually enforced, sender matching is exact, and each destination is explicitly approved.

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

T09 · Insecure Skill Coding Practices

Error
Location
src/channel-bridge.js:50
Finding
Fail-Open and Substring-Based Filters Allow Unauthorized Cross-Channel Message Routing<![CDATA[ ## Vulnerability Details **File Location**: `src/channel-bridge.js:50-63` **Vulnerability Type**: Fail-open authorization filtering and imprecise identity matching **Risk Level**: High ### Vulnerable Code ```js _matchFilter(message, filter) { const text = ((message.body || '') + ' ' + (message.subject || '')).toLowerCase(); const from = (message.from || '').toLowerCase(); if (filter.includes('contains:')) { const term = filter.split('contains:')[1].split(' ')[0].toLowerCase(); if (text.includes(term)) return true; } if (filter.includes('from:')) { const sender = filter.split('from:')[1].split(' ')[0].toLowerCase(); if (from.includes(sender)) return true; } // Unknown filter types pass through (don't silently drop messages) if (!filter.includes('contains:') && !filter.includes('from:')) return true; return false; } ``` The affected behavior is exercised by the documented configuration in `SKILL.md:38-41`: ```yaml - name: "announcements" from: slack filter: "channel:#announcements" to: [discord, telegram, email] transform: "forward" ``` ### Technical Analysis The filter implementation fails open for every filter that does not contain the literal strings `contains:` or `from:`. The documented `channel:#announcements` expression is not implemented, so `_matchFilter()` returns `true` for it regardless of the actual source channel. Consequently, messages from any Slack channel can satisfy a route that appears to be restricted to `#announcements`. The `from:` implementation is also imprecise because it uses substring matching: ```js if (from.includes(sender)) return true; ``` A filter such as `from:boss` therefore accepts identities including `evilboss`, `boss-attacker`, or any other string containing `boss`. It does not compare a canonical account identifier or require an exact identity match. Filters govern whether a message is copied to route destinations, making them an authorization boundary for poten ...[truncated 1832 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace ad hoc string splitting with a strict parser for a documented filter grammar. 2. Explicitly implement every advertised filter type, including channel filters, before presenting it as supported. 3. Reject unknown, malformed, empty, or partially parsed filters during route creation. Filtering errors must fail closed. 4. Resolve platform-specific usernames and channels to canonical immutable identifiers where possible. 5. Compare sender and channel identifiers exactly rather than with `String.prototype.includes()`. 6. Define `AND` and `OR` precedence explicitly and reject expressions that cannot be parsed completely. 7. Validate route objects in `addRoute()` and the constructor, including `from`, `to`, `filter`, `transform`, and `schedule`. 8. Add regression tests proving that: - `channel:#announcements` rejects messages from every other channel. - `from:boss` rejects `evilboss` and `boss-attacker`. - Unknown and malformed filter types reject messages. - Mixed expressions follow their documented Boolean semantics. 9. Return or log a clear configuration error when a filter is unsupported instead of silently forwarding messages. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Vague Triggers

Medium
Confidence
88% confidence
Finding
The description says the skill 'routes messages between' platforms but does not specify what user action, command, or context activates it. For a markdown skill description, this is an ambiguous trigger surface that could lead to unintended invocation because no explicit trigger phrases, constraints, or exclusion conditions are provided.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The use cases encourage forwarding content across Discord, Slack, Telegram, Signal, email, SMS, and WhatsApp without prominently warning that sensitive or regulated data may be replicated into less trusted platforms. This can lead users to unintentionally exfiltrate internal messages, secrets, personal data, or compliance-scoped information across channels with different retention, access, and security properties.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The skill advertises broad any-to-any message routing across multiple external platforms without stating clear activation boundaries, authorization checks, or restrictions on what content may be forwarded. In a cross-channel context, this can enable accidental or unsafe propagation of sensitive data, internal messages, or prompt content between platforms with different trust levels and retention properties.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code routes, transforms, and buffers message contents across destinations, which can transmit user or system data between platforms. There is no confirmation prompt, logging, print statement, or explanatory comment/docstring warning users that message content may be forwarded or retained in a digest buffer.

Scope Creep

Low
Category
Excessive Agency
Content
**USE AT YOUR OWN RISK.**

- The author(s) are NOT liable for any damages, losses, or consequences arising from 
  the use or misuse of this software — including but not limited to financial loss, 
  data loss, security breaches, business interruption, or any indirect/consequential damages.
- This software does NOT constitute financial, legal, trading, or professional advice.
- Users are solely responsible for evaluating whether this software is suitable for
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Scope Creep

Low
Category
Excessive Agency
Content
**USE AT YOUR OWN RISK.**

- The author(s) are NOT liable for any damages, losses, or consequences arising from 
  the use or misuse of this software — including but not limited to financial loss, 
  data loss, security breaches, business interruption, or any indirect/consequential damages.
- This software does NOT constitute financial, legal, trading, or professional advice.
- Users are solely responsible for evaluating whether this software is suitable for
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Static analysis

No suspicious patterns detected.