lib: handle windows reserved device names on UNC

We have found that UNC paths weren't covered
when .join/.normalize windows reserved device
names (COM1, LPT1).

PR-URL: https://github.com/nodejs/node/pull/59286
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Rafael Gonzaga 2025-08-09 09:54:53 -03:00 committed by GitHub
parent 0946c8b28b
commit a73b575304
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 0 deletions

View file

@ -110,6 +110,14 @@ joinTests.push([
[['c:.', 'file'], 'c:file'],
[['c:', '/'], 'c:\\'],
[['c:', 'file'], 'c:\\file'],
// UNC path join tests (Windows)
[['\\server\\share', 'file.txt'], '\\server\\share\\file.txt'],
[['\\server\\share', 'folder', 'another.txt'], '\\server\\share\\folder\\another.txt'],
[['\\server\\share', 'COM1:'], '\\server\\share\\COM1:'],
[['\\server\\share', 'path', 'LPT1:'], '\\server\\share\\path\\LPT1:'],
[['\\fileserver\\public\\uploads', 'CON:..\\..\\..\\private\\db.conf'],
'\\fileserver\\public\\uploads\\CON:..\\..\\..\\private\\db.conf'],
// Path traversal in previous versions of Node.js.
[['./upload', '/../C:/Windows'], '.\\C:\\Windows'],
[['upload', '../', 'C:foo'], '.\\C:foo'],

View file

@ -9,6 +9,19 @@ if (!common.isWindows) {
}
const normalizeDeviceNameTests = [
// UNC paths: \\server\share\... is a Windows UNC path, where 'server' is the network server name and 'share'
// is the shared folder. These are used for network file access and are subject to reserved device name
// checks after the share.
{ input: '\\\\server\\share\\COM1:', expected: '\\\\server\\share\\COM1:' },
{ input: '\\\\server\\share\\PRN:', expected: '\\\\server\\share\\PRN:' },
{ input: '\\\\server\\share\\AUX:', expected: '\\\\server\\share\\AUX:' },
{ input: '\\\\server\\share\\LPT1:', expected: '\\\\server\\share\\LPT1:' },
{ input: '\\\\server\\share\\COM1:\\foo\\bar', expected: '\\\\server\\share\\COM1:\\foo\\bar' },
{ input: '\\\\server\\share\\path\\COM1:', expected: '\\\\server\\share\\path\\COM1:' },
{ input: '\\\\server\\share\\COM1:..\\..\\..\\..\\Windows', expected: '\\\\server\\share\\Windows' },
{ input: '\\\\server\\share\\path\\to\\LPT9:..\\..\\..\\..\\..\\..\\..\\..\\..\\file.txt',
expected: '\\\\server\\share\\file.txt' },
{ input: 'CON', expected: 'CON' },
{ input: 'con', expected: 'con' },
{ input: 'CON:', expected: '.\\CON:.' },
@ -81,6 +94,8 @@ const normalizeDeviceNameTests = [
// Test cases from original vulnerability reports or similar scenarios
{ input: 'COM1:.\\..\\..\\foo.js', expected: '.\\COM1:..\\..\\foo.js' },
{ input: 'LPT1:.\\..\\..\\another.txt', expected: '.\\LPT1:..\\..\\another.txt' },
// UNC paths
{ input: '\\\\?\\COM1:.\\..\\..\\foo2.js', expected: '\\\\?\\COM1:\\foo2.js' },
// Paths with device names not at the beginning
{ input: 'C:\\CON', expected: 'C:\\CON' },