VYPR
High severity8.4OSV Advisory· Published Jan 19, 2026· Updated May 14, 2026

CVE-2026-22031

CVE-2026-22031

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.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
@fastify/middienpm
< 9.1.09.1.0

Affected products

1

Patches

1
d44cd56eb724

fix: decode paths before matching (#245)

https://github.com/fastify/middieKamil MysliwiecJan 3, 2026via ghsa
3 files changed · +51 1
  • lib/engine.js+3 1 modified
    @@ -2,6 +2,7 @@
     
     const reusify = require('reusify')
     const { pathToRegexp } = require('path-to-regexp')
    +const FindMyWay = require('find-my-way')
     
     function middie (complete) {
       const middlewares = []
    @@ -98,7 +99,8 @@ function middie (complete) {
             const fn = middleware.fn
             const regexp = middleware.regexp
             if (regexp) {
    -          const result = regexp.exec(url)
    +          const decodedUrl = FindMyWay.sanitizeUrlPath(url)
    +          const result = regexp.exec(decodedUrl)
               if (result) {
                 req.url = req.url.replace(result[0], '')
                 if (req.url[0] !== '/') {
    
  • package.json+1 0 modified
    @@ -72,6 +72,7 @@
       "dependencies": {
         "@fastify/error": "^4.0.0",
         "fastify-plugin": "^5.0.0",
    +    "find-my-way": "^9.4.0",
         "path-to-regexp": "^8.1.0",
         "reusify": "^1.0.4"
       },
    
  • test/middleware.test.js+47 0 modified
    @@ -217,6 +217,53 @@ test('middlewares with prefix', async t => {
       })
     })
     
    +test('middlewares for encoded paths', async t => {
    +  t.plan(2)
    +
    +  const instance = fastify()
    +  instance.register(middiePlugin)
    +    .after(() => {
    +      instance.use('/encoded', function (req, _res, next) {
    +        req.slashed = true
    +        next()
    +      })
    +      instance.use('/%65ncoded', function (req, _res, next) {
    +        req.slashedSpecial = true
    +        next()
    +      })
    +    })
    +
    +  function handler (request, reply) {
    +    reply.send({
    +      slashed: request.raw.slashed,
    +      slashedSpecial: request.raw.slashedSpecial
    +    })
    +  }
    +
    +  instance.get('/encoded', handler)
    +  instance.get('/%65ncoded', handler)
    +
    +  const fastifyServerAddress = await instance.listen({ port: 0 })
    +  t.after(() => instance.server.close())
    +
    +  await t.test('decode the request url and run the middleware', async (t) => {
    +    t.plan(2)
    +    const response = await fetch(fastifyServerAddress + '/%65ncod%65d') // '/encoded'
    +    t.assert.ok(response.ok)
    +    const body = await response.json()
    +    t.assert.deepStrictEqual(body, { slashed: true })
    +  })
    +
    +  await t.test('does not double decode the url', async (t) => {
    +    t.plan(2)
    +    const response = await fetch(fastifyServerAddress + '/%2565ncoded')
    +    const body = await response.json()
    +
    +    t.assert.ok(response.ok)
    +    t.assert.deepStrictEqual(body, { slashedSpecial: true })
    +  })
    +})
    +
     test('res.end should block middleware execution', (t, done) => {
       t.plan(4)
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.