CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-X43W-PH7M-PFJX

Suicide by Plugin: Use-After-Free in HexChat Rust Bindings

Alon Barad
Alon Barad
Software Engineer

Feb 25, 2026·6 min read·31 visits

Executive Summary (TL;DR)

The `hexchat` Rust crate allows plugins to deregister commands from within the command's own callback, triggering a Use-After-Free. Additionally, it exposes thread-unsafe macros as safe. The crate is unmaintained; no fix exists.

Rust promises memory safety, but when you dance with C libraries via FFI, that promise relies entirely on the quality of the glue code. The `hexchat` crate, a set of Rust bindings for the popular IRC client, contains a fatal flaw in how it manages command lifecycles. By allowing a command callback to capture its own handle and deregister itself during execution, the library enables a classic Use-After-Free scenario. Coupled with thread-safety lies (macros marked safe that aren't), this unmaintained crate serves as a textbook example of how 'Safe Rust' can still segfault if the foundations are rotten.

The Hook: When Safe Rust Isn't

Rust's primary selling point is its borrow checker—a tyrannical compile-time overlord that prevents you from shooting your own foot. But there is a loophole: unsafe blocks and Foreign Function Interfaces (FFI). When you write bindings for a C application like HexChat, you are effectively negotiating a treaty between the strict, orderly world of Rust and the chaotic, pointer-loving Wild West of C.

The hexchat crate was supposed to be the diplomat. It wraps the raw C API of HexChat into 'safe' Rust abstractions, allowing developers to write plugins without worrying about manual memory management. It promises that if your code compiles, it won't segfault.

It lied. Through a combination of poor lifetime management and improper handling of interior mutability, this crate allows a trivial sequence of safe Rust code to corrupt memory. It’s the software equivalent of a safety harness that unclips itself the moment you put weight on it. To make matters worse, the crate is now abandoned, meaning this vulnerability is effectively a permanent feature for anyone still using it.

The Flaw: Ouroboros Memory Corruption

The core vulnerability (CWE-416) is a Use-After-Free triggering a logic error in command deregistration. In the HexChat C API, registering a command gives you a handle. To remove that command, you pass the handle back to HexChat.

The Rust bindings wrap this handle in a struct. The flaw arises because the library developers didn't account for reentrancy combined with interior mutability. Specifically, Rust's ownership rules usually prevent a closure from owning the very object that owns the closure (a cycle). However, using RefCell or Rc, a developer can trick the compiler into allowing a command callback to hold a reference to its own command handle.

Here is the kill chain:

  1. A plugin registers a command (e.g., /explode).
  2. The callback for /explode captures a clone of its own handle using Rc<RefCell<...>>.
  3. When the user types /explode, the callback runs.
  4. Inside the callback, the code calls deregister on the captured handle.
  5. The library immediately frees the memory associated with the command and the callback itself.
  6. The CPU, blissfully unaware that the instructions it is currently executing have just been free()'d, tries to return from the function or access stack variables. Boom.

The Code: Anatomy of a Self-Deleting Closure

Since there is no patch to diff, let's look at the anti-pattern that triggers this. The vulnerability relies on the interaction between hexchat::hook_command and standard Rust interior mutability patterns.

In a healthy system, the API would prevent a callback from destroying its own execution context. The hexchat crate fails to enforce this isolation. A researcher, SoniEx2, documented this behavior purely in safe Rust:

use std::cell::RefCell;
use std::rc::Rc;
use hexchat::{Plugin, CommandHandle};
 
// The handle is wrapped in an Option inside a RefCell inside an Rc
// This allows the closure to mutate the handle that owns the closure.
let cmd_handle: Rc<RefCell<Option<CommandHandle>>> = Rc::new(RefCell::new(None));
let cmd_handle_clone = cmd_handle.clone();
 
*cmd_handle.borrow_mut() = Some(hexchat::hook_command(
    "suicide",
    move |_| {
        // THE SMOKING GUN:
        // We borrow the handle mutably inside the callback...
        if let Some(handle) = cmd_handle_clone.borrow_mut().take() {
            // ...and drop it.
            // This calls the Drop trait, which calls hexchat_unhook.
            // The C side frees the memory for this hook.
            // But we are STILL INSIDE the hook function.
            drop(handle); 
        }
        // Any code executed here is walking on freed memory.
        hexchat::print("If you see this, you got lucky. Next time, maybe not.");
        1 // Return value access might crash
    },
    hexchat::Priority::Normal,
    "Deregisters itself",
));

When drop(handle) is called, the underlying C library destroys the hook data structure. However, the closure body (the Rust function) is still on the stack. When the closure attempts to return or access captured variables after the drop, it accesses invalid memory. This is a text-book Use-After-Free, made possible because the abstraction leaked implementation details (the ability to drop the handle) into the context where the handle is active.

The Threading Nightmare

As if the UAF wasn't enough, the crate also plays fast and loose with thread safety. Rust has two traits, Send and Sync, which automatically ensure safe concurrency. hexchat bypasses these protections using macros.

The crate exposes macros (likely for printing or command execution) that are marked as safe to call. However, the underlying HexChat C API is single-threaded and generally not thread-safe.

If a plugin spins up a background thread (common for network operations) and calls these macros, it invokes C functions that manipulate global state without locks. This leads to Data Races (CWE-662). In the best case, the IRC client crashes. In the worst case, the race condition corrupts the internal state of the IRC client, potentially leading to memory corruption exploitable for code execution. The fact that these macros were not marked unsafe is a direct violation of Rust's API guidelines.

The Exploit: Weaponizing the Crash

Exploiting this in the wild is nuanced because it targets the plugin developer (or the user running a malicious plugin), not the IRC protocol directly. However, the vector exists.

Attack Scenario: The "Time Bomb" Plugin

An attacker distributes a HexChat plugin promising useful features (e.g., "Auto-Reply Bot").

  1. Setup: The plugin registers a command or a timer.
  2. Trigger: The attacker waits for a specific IRC message or a timer event.
  3. Execution: The plugin triggers the self-deregistration UAF path.
  4. Heap Spray: Before the callback returns, the plugin allocates a new object to occupy the just-freed memory slot of the closure environment.
  5. Control Flow Hijack: When the callback finally tries to return or access a variable, it uses the data from the attacker's sprayed object. If the attacker controls the instruction pointer (RIP/EIP), they execute arbitrary shellcode within the context of the HexChat process.

Since HexChat is an IRC client, RCE here means access to private chat logs, file transfers, and the ability to impersonate the user on IRC networks.

The Mitigation: Abandon Ship

Here is the hard truth: There is no patch. The crate is unmaintained. The architectural flaws (allowing self-referential handle dropping) require a significant rewrite of how the Rust bindings manage ownership of C objects.

Remediation Steps

  1. Identify Usage: Run cargo audit in your Rust projects. If hexchat appears, you have a problem.
  2. Migrate: You must switch to a different set of bindings or write your own minimal unsafe FFI wrappers around hexchat.h.
  3. Audit Existing Code: If you are forced to maintain a legacy codebase using this crate, search for RefCell or Mutex usage inside command callbacks. Ensure no handle is ever moved into the closure it controls.
  4. Avoid Threading Macros: Treat all HexChat-related macros as unsafe and wrap them in a mutex that ensures they only run on the main thread.

This vulnerability serves as a grim reminder: A library that hasn't been updated in years isn't "stable"—it's rotting.

Technical Appendix

CVSS Score
8.7/ 10
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:U
EPSS Probability
0.04%

Affected Systems

Rust crates depending on `hexchat`HexChat plugins written in Rust using this crate

Affected Versions Detail

Product
Affected Versions
Fixed Version
hexchat crate
hexchat-rs developers
>= 0.0.0None (Unmaintained)
AttributeDetail
Vulnerability IDGHSA-x43w-ph7m-pfjx
CWECWE-416 (Use After Free)
CVSS v4CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H
PlatformRust / HexChat
Attack VectorLocal / Network (via IRC trigger)
StatusUnmaintained / Unpatched

MITRE ATT&CK Mapping

T1620Reflective Code Loading
Defense Evasion
T1134Access Token Manipulation
Privilege Escalation
CWE-416
Use After Free

References & Sources

  • [1]Original Issue Report by SoniEx2
  • [2]RustSec Advisory 2025-0153
  • [3]GitHub Advisory GHSA-x43w-ph7m-pfjx

More Reports

•about 7 hours ago•CVE-2026-50751
9.3

CVE-2026-50751: Authentication Bypass in Check Point Security Gateway IKEv1 Legacy Validation

An improper authentication vulnerability (CWE-287) exists in the legacy, deprecated Internet Key Exchange version 1 (IKEv1) key exchange protocol implementation in Check Point Security Gateways. The vulnerability is caused by a logic flow weakness during the certificate validation process for Remote Access VPN and Mobile Access (SSL VPN) connections. An unauthenticated remote attacker can exploit this weakness to bypass user authentication entirely, establishing a fully functional Remote Access VPN connection without a valid password.

Alon Barad
Alon Barad
39 views•6 min read
•about 20 hours ago•CVE-2026-39922
6.3

CVE-2026-39922: Server-Side Request Forgery in GeoNode Service Registration Endpoint

GeoNode versions prior to 4.4.5 and 5.0.2 are vulnerable to Server-Side Request Forgery (SSRF) in the service registration endpoint. Authenticated attackers with low privileges can exploit insufficient input validation in the Web Map Service (WMS) registration module to force the application server to make outbound network queries to loopback addresses, private RFC1918 subnets, link-local scopes, and cloud metadata endpoints. This technical report details the mechanics of the vulnerability, the underlying architectural flaw, and how to effectively remediate and mitigate the associated security risks.

Alon Barad
Alon Barad
4 views•7 min read
•1 day ago•CVE-2022-0492
7.8

CVE-2022-0492: Privilege Escalation and Container Escape via cgroups v1 release_agent

CVE-2022-0492 is a high-severity missing authorization vulnerability in the Linux kernel's Control Groups (cgroups) v1 implementation. The flaw resides within the cgroup_release_agent_write function in kernel/cgroup/cgroup-v1.c, where the kernel fails to validate if the process writing to the release_agent file possesses administrative capabilities in the initial user namespace. This allows a local attacker inside a container with root privileges (UID 0) to abuse user namespaces, mount a cgroups v1 directory, modify the release_agent parameter, and execute arbitrary commands on the host system as host root, effectively achieving a complete container escape.

Amit Schendel
Amit Schendel
12 views•7 min read
•3 days ago•GHSA-G72G-R7M4-9X4G
6.3

GHSA-G72G-R7M4-9X4G: Insufficient Session Expiration of OAuth Tokens in NocoDB

NocoDB is subject to an insufficient session expiration vulnerability where OAuth access and refresh tokens are not invalidated or revoked during security-sensitive actions such as password changes, forgot-password requests, or password resets. This allows an attacker possessing an active OAuth token to maintain unauthorized persistence.

Amit Schendel
Amit Schendel
12 views•6 min read
•3 days ago•GHSA-FGMC-2HQJ-86V4
6.9

GHSA-FGMC-2HQJ-86V4: Default Administrative Credentials in vantage6-server

A vulnerability in the vantage6 federated learning framework allows unauthenticated remote attackers to gain administrative control of the server via hardcoded default credentials (root/root) when deployed under default configurations in versions 4.2.3 and below.

Amit Schendel
Amit Schendel
8 views•5 min read
•3 days ago•GHSA-X9F6-9RVM-MMRG
6.9

GHSA-X9F6-9RVM-MMRG: Improper Access Control and Volume Mount Isolation Bypass in vantage6 Node

An improper access control vulnerability in the vantage6 node component allows concurrently running algorithm containers to read and modify sensitive input and output files of other tasks. The lack of strict workspace directory isolation exposes a significant attack surface in multi-tenant or federated environments where untrusted algorithms are executed.

Amit Schendel
Amit Schendel
4 views•4 min read