diff --git a/src/index.js b/src/index.js index 3edaeb1..eacbda1 100644 --- a/src/index.js +++ b/src/index.js @@ -21,6 +21,7 @@ const errorTemplate = require('./error'); const sourceMatches = (source, requestPath, allowSegments) => { const keys = []; const slashed = slasher(source); + const resolvedPath = path.resolve(requestPath); let results = null; @@ -28,7 +29,7 @@ const sourceMatches = (source, requestPath, allowSegments) => { const normalized = slashed.replace('*', '(.*)'); const expression = pathToRegExp(normalized, keys); - results = expression.exec(requestPath); + results = expression.exec(resolvedPath); if (!results) { // clear keys so that they are not used @@ -38,7 +39,7 @@ const sourceMatches = (source, requestPath, allowSegments) => { } } - if (results || minimatch(requestPath, slashed)) { + if (results || minimatch(resolvedPath, slashed)) { return { keys, results diff --git a/test/fixtures/secret b/test/fixtures/secret new file mode 100644 index 0000000..d97c5ea --- /dev/null +++ b/test/fixtures/secret @@ -0,0 +1 @@ +secret diff --git a/test/integration.js b/test/integration.js index d33a91d..bb5c590 100644 --- a/test/integration.js +++ b/test/integration.js @@ -1284,3 +1284,16 @@ test('log error when checking `404.html` failed', async t => { t.is(text, content); }); + +test('prevent access to parent directory', async t => { + const url = await getUrl({ + rewrites: [ + {source: '/secret', destination: '/404.html'} + ] + }); + + const response = await fetch(`${url}/dir/../secret`); + const text = await response.text(); + + t.is(text.trim(), 'Not Found'); +});