Skip to content

Commit 92e65fb

Browse files
authored
Merge pull request from GHSA-3mpf-rcc7-5347
1 parent b38e40e commit 92e65fb

File tree

4 files changed

+68
-4
lines changed

4 files changed

+68
-4
lines changed

deno_dist/middleware/serve-static/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@ export const serveStatic = <E extends Env = Env>(
3030
await next()
3131
return
3232
}
33-
const url = new URL(c.req.url)
3433

35-
let filename = options.path ?? decodeURI(url.pathname)
34+
let filename = options.path ?? decodeURI(c.req.path)
3635
filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename
3736
const root = options.root
3837

runtime_tests/deno/middleware.test.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ Deno.test('Serve Static middleware', async () => {
117117
assertEquals(res.status, 200)
118118
assertEquals(await res.text(), 'Deno!!')
119119
assertSpyCalls(onNotFound, 1)
120+
121+
res = await app.fetch({
122+
method: 'GET',
123+
url: 'http://localhost/static/%2e%2e/static/plain.txt',
124+
} as Request)
125+
assertEquals(res.status, 404)
126+
assertEquals(await res.text(), '404 Not Found')
120127
})
121128

122129
Deno.test('JWT Authentication middleware', async () => {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { createMiddleware } from '../../helper'
2+
import { Hono } from '../../hono'
3+
import { serveStatic as baseServeStatic } from '.'
4+
5+
describe('Serve Static Middleware', () => {
6+
const app = new Hono()
7+
8+
const serveStatic = createMiddleware(async (c, next) => {
9+
const mw = baseServeStatic({
10+
getContent: (path) => {
11+
if (path.endsWith('not-found.txt')) {
12+
return undefined
13+
}
14+
return `Hello in ${path}`
15+
},
16+
pathResolve: (path) => {
17+
return `./${path}`
18+
},
19+
})
20+
return await mw(c, next)
21+
})
22+
23+
app.get('/static/*', serveStatic)
24+
25+
it('Should return 200 response - /static/hello.html', async () => {
26+
const res = await app.request('/static/hello.html')
27+
expect(res.status).toBe(200)
28+
expect(res.headers.get('Content-Type')).toMatch(/^text\/html/)
29+
expect(await res.text()).toBe('Hello in ./static/hello.html')
30+
})
31+
32+
it('Should return 200 response - /static/sub', async () => {
33+
const res = await app.request('/static/sub')
34+
expect(res.status).toBe(200)
35+
expect(res.headers.get('Content-Type')).toMatch(/^text\/html/)
36+
expect(await res.text()).toBe('Hello in ./static/sub/index.html')
37+
})
38+
39+
it('Should decode URI strings - /static/%E7%82%8E.txt', async () => {
40+
const res = await app.request('/static/%E7%82%8E.txt')
41+
expect(res.status).toBe(200)
42+
expect(await res.text()).toBe('Hello in ./static/炎.txt')
43+
})
44+
45+
it('Should return 404 response - /static/not-found', async () => {
46+
const res = await app.request('/static/not-found.txt')
47+
expect(res.status).toBe(404)
48+
expect(await res.text()).toBe('404 Not Found')
49+
})
50+
51+
it('Should not allow a directory traversal - /static/%2e%2e/static/hello.html', async () => {
52+
const res = await app.fetch({
53+
method: 'GET',
54+
url: 'http://localhost/static/%2e%2e/static/hello.html',
55+
} as Request)
56+
expect(res.status).toBe(404)
57+
expect(await res.text()).toBe('404 Not Found')
58+
})
59+
})

src/middleware/serve-static/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@ export const serveStatic = <E extends Env = Env>(
3030
await next()
3131
return
3232
}
33-
const url = new URL(c.req.url)
3433

35-
let filename = options.path ?? decodeURI(url.pathname)
34+
let filename = options.path ?? decodeURI(c.req.path)
3635
filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename
3736
const root = options.root
3837

0 commit comments

Comments
 (0)