Security Functions
The security functions in @ucdjs/path-utils provide robust protection against path traversal attacks, encoding exploits, and boundary violations.
resolveSafePath
Resolves a path safely within a defined base directory boundary, preventing traversal attacks and malicious inputs.
Signature
function resolveSafePath(basePath: string, inputPath: string): string
Parameters
basePath(string) - The base directory that acts as the virtual filesystem root. Must be a non-empty string.inputPath(string) - The path to resolve, which can be relative, absolute, or URL-encoded.
Returns
- (string) - The safely resolved absolute path within the base directory boundary.
Throws
PathTraversalError- If the resolved path would escape the base directoryWindowsDriveMismatchError- If attempting to access a different drive letter on WindowsUNCPathNotSupportedError- If a UNC path is providedIllegalCharacterInPathError- If the path contains null bytes or control charactersFailedToDecodePathError- If the path cannot be safely decoded
Behavior
The function implements a virtual filesystem boundary model:
Absolute Paths
Treated as relative to the boundary root:
resolveSafePath('/home/user', '/config.json')
// → '/home/user/config.json'
Root Reference
The root / points to the boundary root:
resolveSafePath('/home/user', '/')
// → '/home/user'
Current Directory
References point to the base path:
resolveSafePath('/home/user', '.')
// → '/home/user'
Security Features
Path Traversal Prevention
Blocks attempts to escape the boundary:
resolveSafePath('/var/www', '../../etc/passwd')
// ❌ PathTraversalError
Encoding Attack Prevention
Detects and blocks encoded traversal:
resolveSafePath('/var/www', '%2e%2e%2fetc%2fpasswd')
// ❌ PathTraversalError
Control Character Filtering
Rejects null bytes and control chars:
resolveSafePath('/base', 'file\0.txt')
// ❌ IllegalCharacterInPathError
UNC Path Rejection
Blocks Windows UNC network paths:
resolveSafePath('C:\\base', '\\\\server\\share')
// ❌ UNCPathNotSupportedError
Examples
Basic Usage
import { resolveSafePath } from '@ucdjs/path-utils';
const boundary = '/var/www/html';
// Relative paths
resolveSafePath(boundary, 'assets/style.css');
// → '/var/www/html/assets/style.css'
// Absolute paths (treated as relative to boundary)
resolveSafePath(boundary, '/images/logo.png');
// → '/var/www/html/images/logo.png'
// Current directory
resolveSafePath(boundary, './index.html');
// → '/var/www/html/index.html'
// Empty input
resolveSafePath(boundary, '');
// → '/var/www/html'
Windows Paths
const boundary = 'C:\\Projects\\MyApp';
// Windows-style paths
resolveSafePath(boundary, 'src\\index.ts');
// → 'C:/Projects/MyApp/src/index.ts'
// Mixed separators
resolveSafePath(boundary, 'src/components\\Button.tsx');
// → 'C:/Projects/MyApp/src/components/Button.tsx'
// Absolute Windows path within boundary
resolveSafePath(boundary, 'C:\\Projects\\MyApp\\data\\db.json');
// → 'C:/Projects/MyApp/data/db.json'
// Different drive letter
resolveSafePath(boundary, 'D:\\external.txt');
// ❌ WindowsDriveMismatchError
URL-Encoded Paths
// Standard encoding
resolveSafePath('/base', 'file%20name.txt');
// → '/base/file name.txt'
// Path encoding
resolveSafePath('/base', 'path%2Fto%2Ffile.txt');
// → '/base/path/to/file.txt'
// Nested encoding
resolveSafePath('/base', '%252Fconfig%252Fjson');
// → '/base/config/json'
decodePathSafely
Safely decodes a URL-encoded path with protection against infinite loops and malicious nested encodings.
Signature
function decodePathSafely(encodedPath: string): string
Parameters
encodedPath(string) - The URL-encoded path to decode.
Returns
- (string) - The fully decoded path.
Throws
MaximumDecodingIterationsExceededError- If decoding exceeds 10 iterations (malicious input protection)TypeError- If the input is not a string
Behavior
The function decodes paths iteratively until no more encoding is detected:
- Attempts
decodeURIComponent() - Manually decodes common encodings:
%2e→.(dots)%2f→/(forward slashes)%5c→\(backslashes)
- Repeats up to 10 iterations maximum
- Throws error if limit exceeded (prevents infinite loops from malicious inputs)
Examples
import { decodePathSafely } from '@ucdjs/path-utils';
// Standard URL encoding
decodePathSafely('path%20with%20spaces');
// → 'path with spaces'
// Path separators
decodePathSafely('folder%2Ffile.txt');
// → 'folder/file.txt'
// Nested encoding
decodePathSafely('%252e%252e'); // %25 = %, so %252e = %2e = .
// → '..'
// Mixed encoding
decodePathSafely('file%2Ename%20with%20spaces');
// → 'file.name with spaces'
// Malformed encoding (handled gracefully)
decodePathSafely('%XY%ZZ');
// → '%XY%ZZ'
// Excessive nesting (protection)
decodePathSafely(maliciouslyNestedInput);
// ❌ MaximumDecodingIterationsExceededError
isWithinBase
Checks if a resolved path is within a specified base path, considering case sensitivity and platform-specific behavior.
Signature
function isWithinBase(basePath: string, resolvedPath: string): boolean
Parameters
basePath(string) - The base directory boundary to check against.resolvedPath(string) - The path to validate.
Returns
- (boolean) -
trueif the resolved path is within the base path,falseotherwise.
Behavior
Normalization
. and .. segments.Case Sensitivity
Respects filesystem case sensitivity:
- Linux: case-sensitive
- Windows/macOS: case-insensitive
Partial Match Prevention
Prevents partial directory matches:
isWithinBase('/root', '/root2/file')
// → false (not /root/*)
Examples
import { isWithinBase } from '@ucdjs/path-utils';
// Exact match
isWithinBase('/home/user', '/home/user');
// → true
// Within boundary
isWithinBase('/home/user', '/home/user/documents/file.txt');
// → true
// Outside boundary
isWithinBase('/home/user', '/home/other/file.txt');
// → false
// Partial match prevention
isWithinBase('/var/log', '/var/log2/file.txt');
// → false
// Normalized paths
isWithinBase('/home/user', '/home/user/../user/docs/file.txt');
// → true
// Windows paths
isWithinBase('C:\\Users\\John', 'C:\\Users\\John\\Documents\\file.txt');
// → true
// Case sensitivity (on case-sensitive systems)
isWithinBase('/home/user', '/home/User/file.txt');
// → false (on Linux)
// → true (on Windows/macOS)
Best Practices
resolveSafePath as your primary function for user-provided paths. It handles decoding, validation, and boundary enforcement automatically.resolveSafePath before using them in file operations, even if they appear safe.