Skip to content

Commit 137771f

Browse files
author
Peter Bengtsson
authored
Early 404 exits on junk urls (github#37241)
1 parent 42440c7 commit 137771f

2 files changed

Lines changed: 50 additions & 6 deletions

File tree

middleware/handle-invalid-paths.js

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
1-
export default function handleInvalidPaths(req, res, next) {
1+
import { defaultCacheControl } from './cache-control.js'
2+
3+
const JUNK_PATHS = new Set([
4+
'/.env',
5+
'/env',
6+
'/xmlrpc.php',
7+
'/wp-login.php',
8+
'/README.md',
9+
'/server.js',
10+
'/package.json',
11+
'/.git',
12+
])
13+
14+
function isJunkPath(path) {
15+
if (JUNK_PATHS.has(path)) return true
16+
217
// Prevent various malicious injection attacks targeting Next.js
3-
if (req.path.match(/^\/_next[^/]/) || req.path === '/_next/data' || req.path === '/_next/data/') {
18+
if (path.match(/^\/_next[^/]/) || path === '/_next/data' || path === '/_next/data/') {
19+
return true
20+
}
21+
22+
return false
23+
}
24+
25+
export default function handleInvalidPaths(req, res, next) {
26+
if (isJunkPath(req.path)) {
27+
// We can all the CDN to cache these responses because they're
28+
// they're not going to suddenly work in the next deployment.
29+
defaultCacheControl(res)
430
res.setHeader('content-type', 'text/plain')
531
return res.status(404).send('Not found')
632
}

tests/rendering/server.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,27 @@ describe('static routes', () => {
399399
expect((await get('/public/ghae/schema.docs-ghae.graphql')).statusCode).toBe(200)
400400
})
401401

402-
it('does not serve repo contents that live outside the /assets directory', async () => {
403-
expect((await get('/package.json', { followRedirects: true })).statusCode).toBe(404)
404-
expect((await get('/README.md', { followRedirects: true })).statusCode).toBe(404)
405-
expect((await get('/server.js', { followRedirects: true })).statusCode).toBe(404)
402+
test('does not serve repo contents that live outside the /assets directory', async () => {
403+
const paths = ['/package.json', '/README.md', '/server.js', '/.git', '/.env']
404+
for (const path of paths) {
405+
const res = await get(path)
406+
expect(res.statusCode).toBe(404)
407+
expect(res.headers['content-type']).toMatch('text/plain')
408+
expect(res.headers['cache-control']).toMatch(/max-age=[1-9]/)
409+
expect(res.headers['cache-control']).toMatch('public')
410+
}
411+
expect.assertions(4 * paths.length)
412+
})
413+
414+
test('junk requests with or without query strings is 404', async () => {
415+
const paths = ['/env', '/xmlrpc.php', '/wp-login.php']
416+
for (const path of paths) {
417+
const res = await get(`${path}?r=${Math.random()}`)
418+
expect(res.statusCode).toBe(404)
419+
expect(res.headers['content-type']).toMatch('text/plain')
420+
expect(res.headers['cache-control']).toMatch(/max-age=[1-9]/)
421+
expect(res.headers['cache-control']).toMatch('public')
422+
}
423+
expect.assertions(4 * paths.length)
406424
})
407425
})

0 commit comments

Comments
 (0)