VYPR
Moderate severityNVD Advisory· Published Apr 23, 2024· Updated Aug 2, 2024

Hono vulnerable to Restricted Directory Traversal in serveStatic with deno

CVE-2024-32869

Description

Hono is a Web application framework that provides support for any JavaScript runtime. Prior to version 4.2.7, when using serveStatic with deno, it is possible to traverse the directory where main.ts is located. This can result in retrieval of unexpected files. Version 4.2.7 contains a patch for the issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
hononpm
< 4.2.74.2.7

Affected products

1

Patches

1
92e65fbb6e5e

Merge pull request from GHSA-3mpf-rcc7-5347

https://github.com/honojs/honoYusuke WadaApr 23, 2024via ghsa
4 files changed · +68 4
  • deno_dist/middleware/serve-static/index.ts+1 2 modified
    @@ -30,9 +30,8 @@ export const serveStatic = <E extends Env = Env>(
           await next()
           return
         }
    -    const url = new URL(c.req.url)
     
    -    let filename = options.path ?? decodeURI(url.pathname)
    +    let filename = options.path ?? decodeURI(c.req.path)
         filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename
         const root = options.root
     
    
  • runtime_tests/deno/middleware.test.tsx+7 0 modified
    @@ -117,6 +117,13 @@ Deno.test('Serve Static middleware', async () => {
       assertEquals(res.status, 200)
       assertEquals(await res.text(), 'Deno!!')
       assertSpyCalls(onNotFound, 1)
    +
    +  res = await app.fetch({
    +    method: 'GET',
    +    url: 'http://localhost/static/%2e%2e/static/plain.txt',
    +  } as Request)
    +  assertEquals(res.status, 404)
    +  assertEquals(await res.text(), '404 Not Found')
     })
     
     Deno.test('JWT Authentication middleware', async () => {
    
  • src/middleware/serve-static/index.test.ts+59 0 added
    @@ -0,0 +1,59 @@
    +import { createMiddleware } from '../../helper'
    +import { Hono } from '../../hono'
    +import { serveStatic as baseServeStatic } from '.'
    +
    +describe('Serve Static Middleware', () => {
    +  const app = new Hono()
    +
    +  const serveStatic = createMiddleware(async (c, next) => {
    +    const mw = baseServeStatic({
    +      getContent: (path) => {
    +        if (path.endsWith('not-found.txt')) {
    +          return undefined
    +        }
    +        return `Hello in ${path}`
    +      },
    +      pathResolve: (path) => {
    +        return `./${path}`
    +      },
    +    })
    +    return await mw(c, next)
    +  })
    +
    +  app.get('/static/*', serveStatic)
    +
    +  it('Should return 200 response - /static/hello.html', async () => {
    +    const res = await app.request('/static/hello.html')
    +    expect(res.status).toBe(200)
    +    expect(res.headers.get('Content-Type')).toMatch(/^text\/html/)
    +    expect(await res.text()).toBe('Hello in ./static/hello.html')
    +  })
    +
    +  it('Should return 200 response - /static/sub', async () => {
    +    const res = await app.request('/static/sub')
    +    expect(res.status).toBe(200)
    +    expect(res.headers.get('Content-Type')).toMatch(/^text\/html/)
    +    expect(await res.text()).toBe('Hello in ./static/sub/index.html')
    +  })
    +
    +  it('Should decode URI strings - /static/%E7%82%8E.txt', async () => {
    +    const res = await app.request('/static/%E7%82%8E.txt')
    +    expect(res.status).toBe(200)
    +    expect(await res.text()).toBe('Hello in ./static/炎.txt')
    +  })
    +
    +  it('Should return 404 response - /static/not-found', async () => {
    +    const res = await app.request('/static/not-found.txt')
    +    expect(res.status).toBe(404)
    +    expect(await res.text()).toBe('404 Not Found')
    +  })
    +
    +  it('Should not allow a directory traversal - /static/%2e%2e/static/hello.html', async () => {
    +    const res = await app.fetch({
    +      method: 'GET',
    +      url: 'http://localhost/static/%2e%2e/static/hello.html',
    +    } as Request)
    +    expect(res.status).toBe(404)
    +    expect(await res.text()).toBe('404 Not Found')
    +  })
    +})
    
  • src/middleware/serve-static/index.ts+1 2 modified
    @@ -30,9 +30,8 @@ export const serveStatic = <E extends Env = Env>(
           await next()
           return
         }
    -    const url = new URL(c.req.url)
     
    -    let filename = options.path ?? decodeURI(url.pathname)
    +    let filename = options.path ?? decodeURI(c.req.path)
         filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename
         const root = options.root
     
    

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

4

News mentions

0

No linked articles in our index yet.