CVE-2025-64166 Overview
CVE-2025-64166 is a Cross-Site Request Forgery (CSRF) vulnerability identified in Mercurius, a GraphQL adapter for Fastify. The vulnerability exists in versions prior to 16.4.0 and stems from incorrect parsing of the Content-Type header in requests. Specifically, requests with Content-Type values such as application/x-www-form-urlencoded, multipart/form-data, or text/plain could be misinterpreted as application/json. This misinterpretation bypasses the preflight checks performed by the fetch() API, potentially allowing unauthorized actions to be performed on behalf of an authenticated user.
Critical Impact
Attackers can craft malicious web pages that execute unauthorized GraphQL operations against authenticated users, bypassing browser-based CORS protections through Content-Type header manipulation.
Affected Products
- Mercurius GraphQL adapter for Fastify versions prior to 16.4.0
- Applications using Mercurius without explicit CSRF prevention configuration
- GraphQL endpoints accepting requests without proper Content-Type validation
Discovery Timeline
- 2026-03-05 - CVE-2025-64166 published to NVD
- 2026-03-05 - Last updated in NVD database
Technical Details for CVE-2025-64166
Vulnerability Analysis
This CSRF vulnerability exploits a weakness in how Mercurius handles Content-Type header validation. Modern browsers implement Same-Origin Policy and CORS preflight checks to protect against cross-origin requests. However, certain Content-Type values are considered "simple" and do not trigger preflight requests: application/x-www-form-urlencoded, multipart/form-data, and text/plain.
The vulnerability arises because Mercurius incorrectly parses these Content-Type values and processes them as if they were application/json requests. This allows an attacker to craft a malicious form submission from an attacker-controlled website that sends GraphQL queries or mutations to the vulnerable endpoint without triggering CORS preflight checks.
When an authenticated user visits the attacker's page, the browser will automatically include authentication cookies or session tokens with the forged request, allowing the attacker to execute unauthorized operations with the victim's privileges.
Root Cause
The root cause is insufficient Content-Type header validation in the request handling logic. The GraphQL endpoint did not strictly enforce that only application/json Content-Type requests should be processed as GraphQL operations. By accepting and interpreting "simple" Content-Type values as JSON, the application inadvertently disabled the browser's built-in CSRF protections.
Attack Vector
An attacker exploits this vulnerability by hosting a malicious webpage containing a hidden form or script that submits a POST request to the target GraphQL endpoint. The attack flow proceeds as follows:
- Attacker identifies a Mercurius-powered GraphQL endpoint with sensitive mutations
- Attacker crafts a malicious HTML page with a form targeting the GraphQL endpoint
- The form uses application/x-www-form-urlencoded or text/plain Content-Type
- Victim visits the attacker's page while authenticated to the target application
- The browser submits the forged request with the victim's session cookies
- Mercurius processes the request as a valid GraphQL operation
- Unauthorized mutations are executed with the victim's privileges
The following patch introduces CSRF prevention capabilities to Mercurius:
* - Increase body size limit for larger queries
*/
additionalRouteOptions?: Omit<RouteOptions, 'handler' | 'wsHandler' | 'method' | 'url'>
/**
* Enable CSRF prevention
*/
csrfPrevention?: boolean | {
allowedContentTypes?: string[];
requiredHeaders?: string[];
};
}
export type MercuriusOptions = MercuriusCommonOptions & (MercuriusSchemaOptions)
Source: GitHub Commit Update
The patch also adds the CSRF prevention module to the main application logic:
onResolutionHandler,
onExtendSchemaHandler
} = require('./lib/handlers')
const { normalizeCSRFConfig } = require('./lib/csrf')
async function buildCache (opts) {
if (Object.prototype.hasOwnProperty.call(opts, 'cache')) {
Source: GitHub Commit Update
Detection Methods for CVE-2025-64166
Indicators of Compromise
- Unusual GraphQL mutation requests with text/plain or application/x-www-form-urlencoded Content-Type headers
- GraphQL requests originating from external referrer domains
- Spike in sensitive mutations from users with no corresponding UI activity
- Server logs showing GraphQL operations with non-standard Content-Type headers
Detection Strategies
- Monitor application logs for GraphQL requests with Content-Type headers other than application/json
- Implement Content-Type validation alerts at the web application firewall (WAF) level
- Review access logs for GraphQL mutations that lack proper Origin or Referer headers matching your domain
- Deploy browser-side monitoring to detect cross-origin form submissions targeting GraphQL endpoints
Monitoring Recommendations
- Configure logging to capture full request headers on all GraphQL endpoints
- Set up alerts for GraphQL operations with mismatched Content-Type and payload formats
- Monitor for patterns of unauthorized data modifications following user browsing sessions
- Implement real-time detection for requests to GraphQL endpoints from untrusted origins
How to Mitigate CVE-2025-64166
Immediate Actions Required
- Upgrade Mercurius to version 16.4.0 or later immediately
- Enable the new csrfPrevention configuration option in your Mercurius setup
- Review application logs for any evidence of past CSRF exploitation attempts
- Audit GraphQL mutations for sensitive operations that could be targeted
Patch Information
The vulnerability has been addressed in Mercurius version 16.4.0. The patch introduces a new csrfPrevention configuration option that validates Content-Type headers and can require custom headers on requests. Detailed patch information is available in the GitHub Security Advisory and the related pull request.
Workarounds
- Configure a reverse proxy or WAF to reject GraphQL requests with Content-Type values other than application/json
- Implement custom middleware to validate Content-Type headers before requests reach Mercurius
- Require custom headers (e.g., X-Apollo-Operation-Name or X-Requested-With) that cannot be set by simple cross-origin requests
- Consider implementing SameSite cookie attributes to limit cookie transmission on cross-origin requests
# Configuration example for enabling CSRF prevention in Mercurius
# In your Fastify application configuration:
#
# fastify.register(mercurius, {
# schema: typeDefs,
# resolvers: resolvers,
# csrfPrevention: true
# })
#
# For more granular control:
# csrfPrevention: {
# allowedContentTypes: ['application/json'],
# requiredHeaders: ['x-apollo-operation-name']
# }
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

