---
id: 10177
canonical_url: "https://phying.com/item/10177"
title: "Zammad CVE-2026-102489: Session Leak to RCE"
type: "vulnerability"
cve: "CVE-2026-102489"
cvss: null
severity: "high"
vendor: "Zammad"
product: "Zammad"
affected_versions: "Zammad <= 6.3.1"
source_domain: "horizon3.ai"
source_url: "https://horizon3.ai/attack-research/disclosures/cve-2026-102489-zammad-session-leak-rce/"
published_at: "2026-10-07T10:00:00Z"
snapshot_at: "2026-10-26T05:50:00Z"
archived_by: "Phying News (https://phying.com/item/10177)"
lang: "en"
---

# Zammad CVE-2026-102489: Session Leak to RCE

*Author: Zach Hanley · Published: October 7, 2026 · Source: [horizon3.ai](https://horizon3.ai/attack-research/disclosures/cve-2026-102489-zammad-session-leak-rce/)*

![Zammad CVE-2026-102489 Header](https://horizon3.ai/wp-content/uploads/2026/10/261007-Horizon3s-Tales-from-the-Trenches-Anthropics-Mythos-and-Rejetto-HFS-1024x535.png)

## **Introduction**

On 24 September 2026, the Dutch Institute for Vulnerability Disclosure (DIVD) announced publicly that they had suffered a security incident and had attributed it to an “agentic AI powered attack” given the forensic artifacts they discovered during the incident response. They attributed the source of the initial breach to [Zammad](https://github.com/zammad/zammad), a helpdesk and ticketing application.

During their investigation, they determined that two distinct 0-day vulnerabilities were abused:

1. **CVE-2026-102489** – A session hijack that ultimately allows executing code as the `zammad` user.
2. **CVE-2026-102490** – A privilege escalation that allows escalating to `root`.

Soon after, DIVD released further details of the Zammad vulnerabilities and released an Indicators of Compromise script which looked for leaked session cookies in error logs.

## **CVE-2026-102489: Zammad Session Leak**

Given the above details, it was classified as a session hijack and that session cookies would appear in the logs, so we dug in.

We prompted a vulnerability research harness, with Anthropic’s Opus 4.8 as the model, to attempt to identify and reproduce the issues given:

1. The DIVD CSIRT cases
2. The DIVD IOC script
3. The Zammad open-source GitHub repository

After a couple hours, the results were back and the harness did confirm that if there was a way to trigger an error it would leak the session cookie strings, but it was unable to find an unauthenticated trigger request.

### Fuzzing The Code

Re-prompting the agent, we advised it to build fuzzing tooling to target the areas of code it suspected most likely to be associated with the vulnerable area of code. Several minutes later into a fuzzing campaign against the websocket code, it triggered an error that was reflected back to the requestor which contained the session cookies we were looking for.

The vulnerability trigger is a simple single request to the WebSocket endpoint, `/ws`, with a payload of `{"event": "base"}`.

![Code sending a base event to the Zammad WebSocket endpoint to trigger CVE-2026-102489](https://horizon3.ai/wp-content/uploads/2026/10/image.png)  
**Figure 1.** Triggering the leak

The server then reflects this error back to the client, which leaks the cookies for all active users.

![Proof-of-concept exploit showing Zammad session cookies leaked through the WebSocket vulnerability](https://horizon3.ai/wp-content/uploads/2026/10/image-4-1024x273.png)  
**Figure 2.** Example exploit request

### **Understanding the Source**

Starting from the architectural perspective, Zammad is a Ruby application that utilizes websockets. It stores all global connection states in the `@clients` class-level instance variable. The `headers` variable notably includes the session `Cookie` header.

![Zammad websocket_server.rb code storing client headers in the global clients variable](https://horizon3.ai/wp-content/uploads/2026/10/image-1.png)  
**Figure 3.** `websocket_server.rb` storing headers

Every event that occurs in the framework, the `@clients` variable is passed with it. There is no event type or client based filtering.

![Zammad websocket_server.rb code passing client data and headers into the session event handler](https://horizon3.ai/wp-content/uploads/2026/10/image-2.png)  
**Figure 4.** `websocket_server.rb` event dispatching

The base event handler for the session object takes every parameter passed to it and unpacks each key-value pair stored in it. Which means the sensitive cookies are stored inside the `headers` key of the `clients` variable.

![Zammad sessions event base handler assigning supplied parameters as instance variables](https://horizon3.ai/wp-content/uploads/2026/10/image-3.png)  
**Figure 5.** `sessions/event/base.rb` handler

Lastly, in `sessions/event.rb`, the `run()` method returns the entire event’s instance variables in a response to the client when an error occurs.

![Zammad sessions event code returning an error message containing event instance variables](https://horizon3.ai/wp-content/uploads/2026/10/image-5.png)  
**Figure 6.** Returns event variables in response to client

When a client sends `{"event":"base"}`, the dispatcher successfully resolves `Sessions::Event::Base` as a real Ruby constant, instantiates it with the full `@clients` registry mass-assigned onto the object, then fails when `.run` is called – as `Base` has no implementation. Ruby constructs the `NoMethodError` message to include the receiver’s full object representation, which contains every instance variable including `@clients`, and `sessions/event.rb` returns that message string directly to the caller.

### **Authenticated Session to Code Execution**

Once an attacker has a valid admin session cookie from the leak, they can write arbitrary files into the Zammad application directory via the package installation endpoint. By writing a malicious ERB template that overrides the built-in password reset email view, they can trigger its execution by initiating a password reset for any user – causing Zammad’s mailer to render the attacker-controlled template with full Ruby execution privileges, achieving remote code execution as the `zammad` OS user.

![Proof-of-concept exploit confirming remote code execution as the Zammad system user](https://horizon3.ai/wp-content/uploads/2026/10/image-6-1024x534.png)  
**Figure 7.** Exploit in action

Our proof of concept exploit can be found here: [https://github.com/horizon3ai/CVE-2026-102489](https://github.com/horizon3ai/CVE-2026-102489)

Given that the privilege escalation vector we believe to be CVE-2026-102490 remains unpatched, we will be withholding those details.

## References

- [https://csirt.divd.nl/cases/DIVD-2026-00014/](https://csirt.divd.nl/cases/DIVD-2026-00014/)
- [https://csirt.divd.nl/cases/DIVD-2026-00015/](https://csirt.divd.nl/cases/DIVD-2026-00015/)

---
> 📦 **Full-Text Markdown Snapshot** archived by [Phying News](https://phying.com/item/10177) · Original source: [horizon3.ai](https://horizon3.ai/attack-research/disclosures/cve-2026-102489-zammad-session-leak-rce/)
