UNPKG

st

Version:

A module for serving static files. Does etags, caching, etc.

44 lines (36 loc) 1.4 kB
import path from 'node:path' import { fileURLToPath } from 'node:url' import st from '../st.js' import { test } from './support/tap-shim.js' global.dot = true const { req } = await import('./support/dot-common.js') const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) // A percent-encoded separator must not smuggle a `..` past the traversal // guard. `..%2f` (and `..%5c`) only decode to `../` after the path has been // checked, so the check has to run on the decoded path. `dot: true` is needed // to reach this: with the default `dot: false`, the decoded `..` is rejected // independently as a dot-url. `space in filename.txt` lives in the parent of // the served root, so a non-403 here would mean the response left the mount. test('encoded-slash parent traversal is forbidden', (t) => { req('/..%2fspace%20in%20filename.txt', (er, res, body) => { t.error(er) t.equal(res.statusCode, 403) t.end() }) }) test('encoded-backslash parent traversal is forbidden', (t) => { req('/..%5cspace%20in%20filename.txt', (er, res, body) => { t.error(er) t.equal(res.statusCode, 403) t.end() }) }) test('resolved paths cannot leave the root', (t) => { const mount = st({ dot: true, path: path.join(__dirname, 'fixtures', '.dotted-dir') })._this t.equal(mount.getPath('/../space in filename.txt'), 403) t.end() })