Error Classes
The @ucdjs/path-utils package provides detailed error classes to help identify and handle different types of path-related security and validation issues.
Error Hierarchy
All errors extend from the base PathUtilsBaseError class, which extends the native Error class:
PathUtilsBaseError
├── MaximumDecodingIterationsExceededError
├── PathTraversalError
├── WindowsDriveMismatchError
├── FailedToDecodePathError
├── IllegalCharacterInPathError
├── WindowsPathBehaviorNotImplementedError
└── UNCPathNotSupportedError
Error Classes
PathUtilsBaseError
The abstract base class for all path-utils errors.
Signature
abstract class PathUtilsBaseError extends Error {
constructor(message: string, options?: ErrorOptions)
}
Usage
import { PathUtilsBaseError } from '@ucdjs/path-utils';
try {
// Path operations
} catch (error) {
if (error instanceof PathUtilsBaseError) {
// Handle any path-utils error
console.error('Path utility error:', error.message);
}
}
PathTraversalError
Thrown when a path traversal attempt is detected (trying to escape the base directory).
Properties
message(string) - Descriptive error messagebasePath(string) - The allowed base path boundaryaccessedPath(string) - The path that was attempted to be accessed
When Thrown
- When
resolveSafePath()resolves to a path outside the base directory - When encoded traversal attempts are detected (
%2e%2e%2f) - When relative paths with
../escape the boundary
Example
import { resolveSafePath, PathTraversalError } from '@ucdjs/path-utils';
try {
resolveSafePath('/var/www/html', '../../etc/passwd');
} catch (error) {
if (error instanceof PathTraversalError) {
console.error(`Traversal attempt detected!`);
console.error(`Base: ${error.basePath}`);
console.error(`Attempted: ${error.accessedPath}`);
// Base: /var/www/html
// Attempted: /etc/passwd
}
}
WindowsDriveMismatchError
Thrown when attempting to access a path on a different Windows drive letter than the base path.
Properties
message(string) - Descriptive error messagebaseDrive(string) - The drive letter of the base path (e.g.,"C")accessedDrive(string) - The drive letter that was attempted (e.g.,"D")
When Thrown
- When
resolveSafePath()receives paths with different drive letters on Windows - When the input path specifies a different drive than the base path
Example
import { resolveSafePath, WindowsDriveMismatchError } from '@ucdjs/path-utils';
try {
resolveSafePath('C:\\Users\\John', 'D:\\External\\file.txt');
} catch (error) {
if (error instanceof WindowsDriveMismatchError) {
console.error(`Drive mismatch!`);
console.error(`Base drive: ${error.baseDrive}`);
console.error(`Attempted drive: ${error.accessedDrive}`);
// Base drive: C
// Attempted drive: D
}
}
UNCPathNotSupportedError
Thrown when a UNC (Universal Naming Convention) network path is provided.
Properties
message(string) - Descriptive error messagepath(string) - The UNC path that was rejected
When Thrown
- When any function receives a UNC path (
\\server\share) - UNC paths are rejected for security reasons across all functions
Example
import { resolveSafePath, UNCPathNotSupportedError } from '@ucdjs/path-utils';
try {
resolveSafePath('C:\\base', '\\\\server\\share\\file.txt');
} catch (error) {
if (error instanceof UNCPathNotSupportedError) {
console.error(`UNC path rejected: ${error.path}`);
// UNC path rejected: \\server\share\file.txt
}
}
IllegalCharacterInPathError
Thrown when a path contains illegal characters such as null bytes or control characters.
Properties
message(string) - Descriptive error message including the illegal character
When Thrown
- When
resolveSafePath()detects null bytes (\0) in the path - When control characters (Unicode category Cc) are found in the path
Example
import { resolveSafePath, IllegalCharacterInPathError } from '@ucdjs/path-utils';
try {
// Null byte injection attempt
resolveSafePath('/base', 'safe.txt\0../../../etc/passwd');
} catch (error) {
if (error instanceof IllegalCharacterInPathError) {
console.error('Illegal character detected:', error.message);
// Illegal character detected: Illegal character detected in path: '\0'
}
}
try {
// Control character
resolveSafePath('/base', 'file\x01.txt');
} catch (error) {
if (error instanceof IllegalCharacterInPathError) {
console.error('Control character found');
}
}
FailedToDecodePathError
Thrown when a path cannot be safely decoded.
When Thrown
- When
decodePathSafely()exceeds the maximum decoding iterations (10) - Indicates potential malicious input with excessive nested encoding
Example
import { resolveSafePath, FailedToDecodePathError } from '@ucdjs/path-utils';
// Maliciously nested encoding
const maliciousInput = '%25252525...'; // Many layers deep
try {
resolveSafePath('/base', maliciousInput);
} catch (error) {
if (error instanceof FailedToDecodePathError) {
console.error('Path decoding failed - possible attack');
}
}
MaximumDecodingIterationsExceededError
Thrown when path decoding exceeds the safety limit of 10 iterations.
When Thrown
- When
decodePathSafely()detects more than 10 layers of URL encoding - Protection against infinite loops from malicious inputs
Example
import { decodePathSafely, MaximumDecodingIterationsExceededError } from '@ucdjs/path-utils';
// Create deeply nested encoding
let malicious = 'attack';
for (let i = 0; i < 15; i++) {
malicious = encodeURIComponent(malicious);
}
try {
decodePathSafely(malicious);
} catch (error) {
if (error instanceof MaximumDecodingIterationsExceededError) {
console.error('Too many encoding layers - rejecting input');
}
}
WindowsPathBehaviorNotImplementedError
Thrown when an unsupported Windows path behavior is encountered.
When Thrown
- When
resolveSafePath()encounters Windows path combinations that aren't implemented - Rare edge case for future Windows path handling features
Example
import { WindowsPathBehaviorNotImplementedError } from '@ucdjs/path-utils';
try {
// Some unsupported Windows path scenario
} catch (error) {
if (error instanceof WindowsPathBehaviorNotImplementedError) {
console.error('Unsupported Windows path behavior');
}
}
Error Handling Patterns
Specific Error Handling
import {
resolveSafePath,
PathTraversalError,
WindowsDriveMismatchError,
UNCPathNotSupportedError,
IllegalCharacterInPathError,
} from '@ucdjs/path-utils';
function safelyHandlePath(basePath: string, userInput: string): string {
try {
return resolveSafePath(basePath, userInput);
} catch (error) {
if (error instanceof PathTraversalError) {
throw new Error('Access denied: path outside allowed directory');
}
if (error instanceof WindowsDriveMismatchError) {
throw new Error('Access denied: different drive letter');
}
if (error instanceof UNCPathNotSupportedError) {
throw new Error('Network paths are not supported');
}
if (error instanceof IllegalCharacterInPathError) {
throw new Error('Invalid characters in path');
}
throw error; // Re-throw unexpected errors
}
}
Generic Error Handling
import { resolveSafePath, PathUtilsBaseError } from '@ucdjs/path-utils';
function handlePath(basePath: string, userInput: string): string | null {
try {
return resolveSafePath(basePath, userInput);
} catch (error) {
if (error instanceof PathUtilsBaseError) {
// Log security event
console.warn('Path security violation:', error.message);
return null;
}
throw error; // Non path-utils errors
}
}
Logging Security Events
import { resolveSafePath, PathTraversalError } from '@ucdjs/path-utils';
function logSecurityEvent(error: Error, userInput: string, userId?: string) {
console.error({
type: 'security_violation',
error: error.name,
message: error.message,
input: userInput,
userId,
timestamp: new Date().toISOString(),
});
}
try {
const path = resolveSafePath('/base', userInput);
} catch (error) {
if (error instanceof PathTraversalError) {
logSecurityEvent(error, userInput, currentUserId);
// Return 403 Forbidden to client
}
}
Best Practices
Always Catch Errors
Log Security Events
PathTraversalError and IllegalCharacterInPathError as potential security incidents.User-Friendly Messages
Check Error Types
instanceof checks to handle different error types appropriately.