CVE-2024-23841 Overview
CVE-2024-23841 is a cross-site scripting (XSS) vulnerability in the @apollo/experimental-apollo-client-nextjs NPM package, which provides Apollo Client support for the Next.js App Router. The package fails to properly escape data embedded in server-side rendered (SSR) HTML output, allowing attackers to inject executable script into the rendered page [CWE-80]. Exploitation requires an attacker to introduce malicious input through a crafted link or by persisting hostile payloads in a GraphQL data source that the client later renders. The maintainers resolved the issue in version 0.7.0 by escaping JSON strings embedded in HTML transport payloads.
Critical Impact
Successful exploitation lets an attacker execute arbitrary JavaScript in the context of the victim's browser session, enabling session theft, UI manipulation, or redirection to attacker-controlled destinations.
Affected Products
- @apollo/experimental-apollo-client-nextjs versions prior to 0.7.0
- Apollo Client integrations using the Next.js App Router SSR data transport
- Node.js runtime deployments of the vulnerable package
Discovery Timeline
- 2024-01-30 - CVE-2024-23841 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2024-23841
Vulnerability Analysis
The @apollo/experimental-apollo-client-nextjs package serializes Apollo Client cache data into HTML during server-side rendering so the browser can hydrate it on the client. Before version 0.7.0, the SSR data transport layer embedded GraphQL response data as JSON directly inside <script> tags without escaping HTML-significant characters. An attacker who controls any field returned by the GraphQL server, or who can influence query variables through a crafted link, can inject a </script> sequence followed by arbitrary JavaScript.
Because the injected payload executes in the application's origin, it inherits access to cookies, local storage, and authenticated API endpoints. The attack requires user interaction, typically clicking a malicious link, but no authentication is needed.
Root Cause
The dataTransport.ts module serialized Apollo Client state using JSON.stringify and inlined the result into the HTML stream. JSON serialization alone does not neutralize the <, >, and & characters, nor the Unicode line separators U+2028 and U+2029, which are valid in JSON but can terminate a script context or break JavaScript parsing. This gap allowed GraphQL response fields or query inputs to escape the surrounding <script> element.
Attack Vector
An attacker either persists a malicious value in a GraphQL-backed data store or crafts a URL whose query parameters flow into a GraphQL query executed during SSR. When a victim loads the page, the server renders the poisoned data into HTML. The browser then parses the injected markup and executes the attacker's script.
// Patch: package/src/util/htmlescape.ts
// Introduced in version 0.7.0 to escape HTML-sensitive characters
// in JSON embedded within <script> tags.
const ESCAPE_LOOKUP: { [match: string]: string } = {
"&": "\\\u0026",
">": "\\\u003e",
"<": "\\\u003c",
"\\u2028": "\\\u2028",
"\\u2029": "\\\u2029",
};
export const ESCAPE_REGEX = /[&><\\u2028\\u2029]/g;
export function htmlEscapeJsonString(str: string): string {
return str.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
}
Source: GitHub Commit b92bc42
Detection Methods for CVE-2024-23841
Indicators of Compromise
- SSR HTML responses containing unescaped </script> sequences inside Apollo state hydration blocks
- GraphQL responses containing characters such as <, >, or Unicode line separators U+2028 / U+2029 in string fields rendered server-side
- Unexpected outbound requests from client browsers immediately after page load, indicating injected script execution
Detection Strategies
- Audit the installed version of @apollo/experimental-apollo-client-nextjs across package manifests and lockfiles; any version below 0.7.0 is vulnerable
- Inspect server-rendered HTML for Apollo cache payloads to confirm JSON fields are escaped using \\u003c, \\u003e, and \\u0026 sequences
- Review GraphQL query logs for inputs containing HTML tags, event handlers, or javascript: URIs that could flow into SSR output
Monitoring Recommendations
- Enable a strict Content Security Policy (CSP) and alert on script-src violations reported from production Next.js origins
- Monitor web application firewall logs for query parameters containing <script>, onerror=, or encoded script fragments targeting Apollo-backed routes
- Track dependency updates in CI/CD pipelines and fail builds that resolve vulnerable Apollo Client Next.js versions
How to Mitigate CVE-2024-23841
Immediate Actions Required
- Upgrade @apollo/experimental-apollo-client-nextjs to version 0.7.0 or later across all Next.js projects
- Rebuild and redeploy affected applications after the dependency update to replace cached SSR bundles
- Rotate session tokens if logs indicate requests carrying script payloads reached vulnerable endpoints
Patch Information
The fix was committed in GitHub commit b92bc42abd5f8e17d4db361c36bd08e4f541a46b and documented in GitHub Security Advisory GHSA-rv8p-rr2h-fgpg. The patch introduces an htmlEscapeJsonString helper that escapes &, <, >, U+2028, and U+2029 in JSON serialized into HTML.
Workarounds
- Validate and sanitize all GraphQL query variables derived from user-controlled URLs or form inputs
- Apply server-side output filters that reject GraphQL responses containing raw HTML control characters in string fields
- Deploy a Content Security Policy that disallows inline scripts without a nonce, reducing the impact of injected <script> content
# Upgrade the vulnerable package to the patched release
npm install @apollo/experimental-nextjs-app-support@^0.7.0
# Verify the installed version
npm ls @apollo/experimental-nextjs-app-support
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

