Back to skill

Security audit

Airc

Security checks for vulnerabilities and agentic risk

Overview

This IRC skill mostly matches its stated purpose, but its bundled defaults and input handling create avoidable risks for private or operational chat use.

Review the configuration before installing or using this skill. Enable TLS certificate verification, prefer a proper hostname over the bundled IP address, and avoid passing untrusted text into nick, channel, reason, or message fields until control-character validation is added. Do not use it for sensitive IRC conversations unless local logging behavior and retention are clearly understood.

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
config.json:2
Finding
TLS Certificate Validation Disabled for the Default IRC Connection## Vulnerability Details **File Location**: `config.json:2-5`; supporting connection logic at `irc.js:50-55` **Vulnerability Type**: Improper TLS certificate validation **Risk Level**: High ### Vulnerable Code `config.json:2-5`: ```json "server": "95.216.77.237", "port": 6697, "tls": true, "verifyTLS": false, ``` `irc.js:50-55`: ```js const connectFn = this.config.tls ? tlsConnect : createConnection; const connectOpts = { host: this.config.server, port: this.config.port, rejectUnauthorized: this.config.tls ? this.config.verifyTLS !== false : undefined }; ``` ### Technical Analysis The bundled configuration explicitly sets `verifyTLS` to `false`. The connection logic translates this setting into `rejectUnauthorized: false`, instructing Node.js to accept certificates that are untrusted, expired, self-signed, or issued for a different host. Although the connection remains encrypted, the remote endpoint is not authenticated. An attacker capable of intercepting network traffic can present an arbitrary certificate and impersonate the configured IRC server. The use of a bare IP address further complicates proper hostname-based certificate validation. ### Attack Path 1. A user invokes an IRC operation such as `connect`, `send`, or `listen`. 2. The client loads `config.json`, including `"tls": true` and `"verifyTLS": false`. 3. The client establishes a TLS connection with `rejectUnauthorized` disabled. 4. A network-positioned attacker intercepts or redirects the connection. 5. The attacker presents a forged or self-signed certificate, which the client accepts. 6. The attacker proxies, reads, modifies, injects, or suppresses IRC traffic while impersonating the configured server. ### Impact Assessment Exploitation requires a network interception position, DNS/routing influence, or control of an intermediary network. It does not directly grant local operating-system privileges. A successful ...[truncated 389 chars]
Remediation
## Remediation Suggestions - Remove `"verifyTLS": false` and enable certificate verification by default. - Set `rejectUnauthorized: true` unconditionally for TLS connections rather than allowing insecure configuration to silently disable authentication. - Use the canonical DNS hostname of the IRC service instead of a bare IP address so hostname verification can operate correctly. - Fail closed when the certificate is invalid, expired, untrusted, or does not match the configured hostname. - If a private certificate authority is required, configure its CA certificate explicitly instead of disabling validation. - Clearly separate explicitly requested plaintext development connections from production TLS connections and display a prominent warning for any insecure mode.

T09 · Insecure Skill Coding Practices

Error
Location
irc.js:229
Finding
IRC Command Injection Through Unvalidated Outbound Protocol Fields## Vulnerability Details **File Location**: `irc.js:229-239`; additional affected registration fields at `irc.js:58-59` **Vulnerability Type**: CRLF-based IRC protocol command injection **Risk Level**: High ### Vulnerable Code `irc.js:229-239`: ```js join(channel) { this.send(`JOIN ${channel}`); } part(channel, reason) { this.send(`PART ${channel}${reason ? ' :' + reason : ''}`); } say(target, message) { this.send(`PRIVMSG ${target} :${message}`); } ``` Registration fields are constructed in the same unsafe manner at `irc.js:58-59`: ```js this.send(`NICK ${this.nick}`); this.send(`USER ${this.config.username} 0 * :${this.config.realname}`); ``` The final protocol framing occurs in `irc.js:103-107`: ```js send(line) { if (this.socket && !this.socket.destroyed) { this.socket.write(line + '\r\n'); } } ``` ### Technical Analysis IRC commands are line-oriented and delimited by carriage-return and line-feed characters. The client interpolates nicknames, usernames, real names, channels, part reasons, message targets, and message bodies directly into protocol lines without rejecting `\r`, `\n`, or NUL characters. If an attacker can influence a CLI argument or configuration value, a crafted value can terminate the intended IRC command and append one or more additional commands. The `send()` method then adds another delimiter but does not neutralize delimiters already embedded in the supplied value. For example, an attacker-controlled message equivalent to `hello\r\nJOIN #attacker` would cause the server to receive the intended `PRIVMSG` followed by an independent `JOIN` command. The exact available effects depend on commands supported by the IRC server and the privileges of the connected IRC identity. ### Attack Path 1. An application, automation workflow, or agent passes attacker-influenced content through `--message`, `--channel`, `--nick`, or another supported fi ...[truncated 1139 chars]
Remediation
## Remediation Suggestions - Reject carriage returns, line feeds, NUL bytes, and other prohibited control characters in every outbound field. - Validate nicknames, usernames, channel names, and message targets against strict IRC-compatible allowlists and length limits. - Apply validation inside the protocol API itself rather than relying only on CLI validation, ensuring every caller receives the same protection. - Introduce a dedicated IRC command serializer that validates each parameter according to whether it is a middle or trailing IRC parameter. - Enforce the server's maximum line length after UTF-8 encoding and safely split long chat messages where appropriate. - Treat configuration data and all CLI arguments as untrusted input. - Add tests covering CRLF, lone CR/LF, NUL, Unicode control characters, oversized values, malformed channels, and malformed nicknames.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (1)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill documents a daemon mode that persistently writes all incoming IRC activity to `messages.jsonl`, but it does not clearly warn users that this creates durable local logs of potentially sensitive communications. In an IRC context, channels and private messages may contain credentials, personal data, or operational details, so silent persistence increases privacy, retention, and exfiltration risk.

Static analysis

No suspicious patterns detected.