CVE-2026-33128 Overview
CVE-2026-33128 is a Server-Sent Events (SSE) injection vulnerability in H3, a minimal HTTP framework for Node.js. The vulnerability exists in versions prior to 1.15.6 and between 2.0.0 through 2.0.1-rc.14 due to missing newline sanitization in the formatEventStreamMessage() and formatEventStreamComment() functions. An attacker who controls any part of an SSE message field (id, event, data, or comment) can inject arbitrary SSE events to connected clients.
Critical Impact
This vulnerability allows attackers to inject malicious Server-Sent Events to all connected clients, potentially enabling cross-site scripting attacks, session hijacking, or manipulation of real-time data streams in applications using the H3 framework.
Affected Products
- H3 HTTP Framework versions prior to 1.15.6 (Node.js)
- H3 HTTP Framework version 2.0.0 (Node.js)
- H3 HTTP Framework versions 2.0.1-rc2 through 2.0.1-rc.14 (Node.js)
Discovery Timeline
- 2026-03-20 - CVE-2026-33128 published to NVD
- 2026-03-20 - Last updated in NVD database
Technical Details for CVE-2026-33128
Vulnerability Analysis
This vulnerability is classified as CWE-93 (Improper Neutralization of CRLF Sequences), commonly known as CRLF Injection. The H3 framework's event stream utilities fail to properly sanitize newline characters in user-controlled input before constructing SSE messages. Server-Sent Events use a specific text-based protocol where fields are separated by newlines, and events are terminated by double newlines. Without proper sanitization, an attacker can inject additional fields or entirely new events by including newline characters in message content.
The vulnerable functions formatEventStreamMessage() and formatEventStreamComment() directly interpolate user input into the SSE message format without escaping or removing newline characters. This allows an attacker to break out of the intended field context and inject arbitrary SSE protocol elements that will be interpreted by connected browsers as legitimate server events.
Root Cause
The root cause is insufficient input validation in the event stream formatting functions within src/utils/internal/event-stream.ts. The functions formatEventStreamMessage() and formatEventStreamComment() did not sanitize newline characters (\n) from the id, event, data, and comment fields before incorporating them into the SSE output format. Since the SSE protocol uses newlines as field delimiters and double newlines as event terminators, unsanitized newlines allow injection of arbitrary protocol elements.
Attack Vector
The attack requires network access without authentication or user interaction. An attacker must be able to influence data that gets passed to the SSE message formatting functions. This could occur in applications where user input is reflected in real-time notifications, chat messages, or status updates delivered via Server-Sent Events. By injecting newline sequences followed by malicious SSE field definitions, an attacker can send arbitrary events to all clients connected to the event stream.
For example, if an attacker controls a comment field, they could inject content like malicious\n\nevent: attack\ndata: payload which would terminate the current comment and inject an entirely new event that all connected clients would receive and process.
// Patch showing the security fix in src/utils/internal/event-stream.ts
// Source: https://github.com/h3js/h3/commit/7791538e15ca22437307c06b78fa155bb73632a6
}
export function formatEventStreamComment(comment: string): string {
- return `: ${comment}\n\n`;
+ return (
+ comment
+ .split("\n")
+ .map((l) => `: ${l}\n`)
+ .join("") + "\n"
+ );
}
export function formatEventStreamMessage(message: EventStreamMessage): string {
let result = "";
if (message.id) {
- result += `id: ${message.id}\n`;
+ result += `id: ${_sanitizeSingleLine(message.id)}\n`;
}
if (message.event) {
- result += `event: ${message.event}\n`;
+ result += `event: ${_sanitizeSingleLine(message.event)}\n`;
}
if (typeof message.retry === "number" && Number.isInteger(message.retry)) {
result += `retry: ${message.retry}\n`;
}
- result += `data: ${message.data}\n\n`;
+ const data = typeof message.data === "string" ? message.data : "";
+ for (const line of data.split("\n")) {
+ result += `data: ${line}\n`;
+ }
Source: GitHub Commit
Detection Methods for CVE-2026-33128
Indicators of Compromise
- Unusual SSE messages containing unexpected newline sequences in application logs
- Client-side JavaScript errors related to malformed or unexpected event stream data
- Anomalous event types appearing in SSE connections that were not defined by the application
- User reports of unexpected behavior in real-time features powered by Server-Sent Events
Detection Strategies
- Monitor web application logs for SSE endpoints receiving input containing newline characters (\n, \r\n, or %0A, %0D%0A URL-encoded variants)
- Implement input validation logging to detect attempts to inject CRLF sequences into event stream parameters
- Review client-side event handlers for unexpected event types being received that don't match application design
- Deploy web application firewall (WAF) rules to detect and block CRLF injection patterns in requests to SSE endpoints
Monitoring Recommendations
- Enable detailed request logging on all endpoints that utilize the H3 createEventStream functionality
- Set up alerts for abnormal patterns in SSE traffic volume or message content anomalies
- Monitor for client-side security errors that may indicate injection attempts are being processed
How to Mitigate CVE-2026-33128
Immediate Actions Required
- Upgrade H3 framework to version 1.15.6 or 2.0.1-rc.15 or later immediately
- Audit all applications using H3's createEventStream to identify potentially vulnerable endpoints
- Review and validate all user input that flows into SSE message fields before the upgrade can be applied
- Consider temporarily disabling SSE functionality in critical applications until patching is complete
Patch Information
The vulnerability has been fixed in H3 versions 1.15.6 and 2.0.1-rc.15. The patch implements proper newline sanitization by splitting multi-line input and formatting each line as a separate SSE field entry, preventing injection of arbitrary protocol elements. The fix applies to the id, event, data, and comment fields in SSE messages.
For detailed patch information, see the GitHub Security Advisory and the commit implementing the fix.
Workarounds
- Implement server-side input sanitization to strip or escape newline characters from any user-controlled data before passing it to SSE message functions
- Add input validation at the application layer to reject or sanitize inputs containing newline sequences before they reach H3's event stream functions
- Deploy a reverse proxy or WAF rule to filter requests containing CRLF sequences targeting SSE endpoints
# Update H3 framework using npm
npm update h3@1.15.6
# Or for version 2.x
npm update h3@2.0.1-rc.15
# Verify installed version
npm list h3
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

