diff --git a/lib/index.test.ts b/lib/index.test.ts index 7e70410..78c5989 100644 --- a/lib/index.test.ts +++ b/lib/index.test.ts @@ -192,4 +192,8 @@ describe('sanitize() - Vulnerability Tests', () => { it('Protects reported vulnerability #1', () => { expect(linuxSlash(join('/var/app-dir', sanitize("..=%5c..=%5c..=%5c..=%5c..=%5c..=%5c..=%5cetc/passwd")))).not.toBe('/etc/passwd') }) + + it('Protects reported vulnerability #2', () => { + expect(linuxSlash(join('/var/app', sanitize("./../../test/../../../../../../../../../../etc/passwd")))).not.toBe('/etc/passwd') + }) }) diff --git a/lib/index.ts b/lib/index.ts index f1d4dae..3c08a33 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -103,6 +103,20 @@ export default function sanitize(pathstr: string, options: SanitizeOptions = DEF // Replace double (back)slashes with a single slash sanitizedPath = sanitizedPath.replace(/[\/\\]+/g, '/') + // Replace /../ with / + sanitizedPath = sanitizedPath.replace(options.parentDirectoryRegEx, '/') + + // Remove ./ or / at start + while (sanitizedPath.startsWith('/') || sanitizedPath.startsWith('./') || sanitizedPath.endsWith('/..') || sanitizedPath.endsWith('/../') || sanitizedPath.startsWith('../') || sanitizedPath.startsWith('/../')) { + sanitizedPath = sanitizedPath.replace(/^\.\//g, '') // ^./ + sanitizedPath = sanitizedPath.replace(/^\//g, '') // ^/ + // Remove ../ | /../ at pos 0 and /.. | /../ at end + sanitizedPath = sanitizedPath.replace(/^[\/\\]\.\.[\/\\]/g, '/') + sanitizedPath = sanitizedPath.replace(/^\.\.[\/\\]/g, '/') + sanitizedPath = sanitizedPath.replace(/[\/\\]\.\.$/g, '/') + sanitizedPath = sanitizedPath.replace(/[\/\\]\.\.\/$/g, '/') + } + // Make sure out is not "." sanitizedPath = sanitizedPath.trim() === '.' ? '' : sanitizedPath