VYPR
Low severityNVD Advisory· Published Feb 25, 2025· Updated Feb 25, 2025

Matrix IRC Bridge allows IRC command injection to own puppeted user

CVE-2025-27146

Description

matrix-appservice-irc is a Node.js IRC bridge for Matrix. The matrix-appservice-irc bridge up to version 3.0.3 contains a vulnerability which can lead to arbitrary IRC command execution as the puppeted user. The attacker can only inject commands executed as their own IRC user. The vulnerability has been patched in matrix-appservice-irc version 3.0.4.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Unsanitized newlines in Matrix room topics enable IRC command injection in matrix-appservice-irc < 3.0.4, allowing attackers to execute arbitrary IRC commands as their own bridged user.

Vulnerability

Overview The matrix-appservice-irc bridge, a Node.js IRC bridge for Matrix, contains a vulnerability in versions prior to 3.0.4 that allows arbitrary IRC command execution. The root cause is insufficient sanitization of input when setting a Matrix room topic, which is then forwarded to IRC through the TOPIC command. When a Matrix user changes a room topic containing newline characters, the bridge passes the raw string to the IRC server, effectively allowing an attacker to inject additional IRC commands on the same connection. The fix, introduced in commit 74f02c8e11f16ed1b355700092c1aa9c036a11bd, replaces newline characters (\n) with pipes (|) and strips carriage returns (\r) before sending the topic to IRC. [1][3][4]

Attack

Vector Exploitation requires the attacker to be a Matrix user who has permission to change the room topic in a bridged channel. The attacker sets a topic containing newlines followed by arbitrary IRC commands (e.g., /msg, JOIN, PRIVMSG). When the bridge processes the topic change, it forwards the unsanitized string to the IRC server via the TOPIC command, causing the injected newlines to terminate the TOPIC command and execute subsequent lines as new IRC commands. The attack is limited to the attacker's own IRC user context, meaning the attacker cannot impersonate other users or execute commands as a different IRC client. [1][4]

Impact

A successful attack allows the attacker to execute arbitrary IRC commands as their own bridged user, potentially including actions such as joining or leaving channels, sending private messages, changing nicknames, or interacting with IRC services (e.g., NickServ commands). The scope is limited to the attacker's own puppeted IRC client, so there is no privilege escalation to other users or to the bridge itself. Commands are executed with the permissions and capabilities of the attacker's IRC account. [1][4]

Mitigation

The vulnerability has been patched in matrix-appservice-irc version 3.0.4. All users running a version prior to 3.0.4 should update immediately to the latest release. No workarounds are documented. The attack surface is limited to topic changes, but bridge operators should ensure timely patching to prevent abuse. [1][4]

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
matrix-appservice-ircnpm
< 3.0.43.0.4

Affected products

3

Patches

1
74f02c8e11f1

irc: BridgedClient.ts: replace newlines with pipes "|"

https://github.com/matrix-org/matrix-appservice-ircFerass El HafidiDec 15, 2024via ghsa
1 file changed · +6 2
  • src/irc/BridgedClient.ts+6 2 modified
    @@ -909,13 +909,17 @@ export class BridgedClient extends EventEmitter {
         }
     
         private async setTopic(room: IrcRoom, topic: string): Promise<void> {
    +        // replace newline "\n" with a pipe "|" to follow IRC conventions
    +        const sanitized_topic = topic.replace(/\n/g, " | ").replace(/\r/g, "")
    +
             if (this.state.status !== BridgedClientStatus.CONNECTED) {
                 throw Error("unsafeClient not ready yet");
             }
             // join the room if we haven't already
             await this.joinChannel(room.channel);
    -        this.log.info("Setting topic to %s in channel %s", topic, room.channel);
    -        return this.state.client.send("TOPIC", room.channel, topic);
    +
    +        this.log.info("Setting topic to %s in channel %s", sanitized_topic, room.channel);
    +        return this.state.client.send("TOPIC", room.channel, sanitized_topic);
         }
     
         private async sendMessage(room: IrcRoom, msgType: string, text: string, expiryTs: number) {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.