FlowiseAI/Flowise · critical · Error
Invalid filename: unsafe characters or path traversal attemp
Error message
Invalid filename: unsafe characters or path traversal attempt detected in filename "${filename}" What it means
Thrown by validateFilename when isUnsafeFilePath(filename) returns true — i.e. the filename contains directory traversal (..), URL-encoded separators (%2f, %5c), null/control bytes, absolute paths, UNC paths, or extended-length path prefixes. This is the CVE path-traversal mitigation: filenames must be relative basenames.
Source
Thrown at packages/components/src/validator.ts:106
/^[a-zA-Z]:\\/, // Absolute Windows paths (C:\)
/^\\\\[^\\]/, // UNC paths (\\server\)
/^\\\\\?\\/ // Extended-length paths (\\?\)
]
return dangerousPatterns.some((pattern) => pattern.test(filePath))
}
/**
* Validates filename format and security
* @param {string} filename The filename to validate
* @returns {void} Throws an error if validation fails
*/
const validateFilename = (filename: string): void => {
if (!filename || typeof filename !== 'string') {
throw new Error('Invalid filename: filename is required and must be a string')
}
if (isUnsafeFilePath(filename)) {
throw new Error(`Invalid filename: unsafe characters or path traversal attempt detected in filename "${filename}"`)
}
}
/**
* Extracts and normalizes file extension from filename
* @param {string} filename The filename
* @returns {string} The normalized extension (lowercase, without dot) or empty string
*/
const extractFileExtension = (filename: string): string => {
const filenameParts = filename.split('.')
if (filenameParts.length <= 1) {
return ''
}
let ext = filenameParts.pop()!.toLowerCase()
// Normalize common extension variations to match MIME type mappings
const extensionNormalizationMap: { [key: string]: string } = {
jpeg: 'jpg', // image/jpeg and image/jpg both map to 'jpg'
tif: 'tiff', // image/tiff and image/tif both map to 'tiff'View on GitHub (pinned to abe4a8601a)
Solutions
- Sanitize with a basename extraction (path.basename) before validation, or use the sanitize-filename library already imported.
- Reject the upload with a 400 and require the client to send a plain basename.
- Never concatenate user-supplied filenames into filesystem paths without re-validating the resolved path stays within the target dir.
Example fix
// before validateFilename(filename) // throws on '../' // after — coerce to a safe basename first const safeName = path.basename(filename || '').trim() validateFilename(safeName) // or use the imported sanitize() for stricter cleaning const clean = sanitize(filename || '') validateFilename(clean)
Defensive patterns
Strategy: validation
Validate before calling
import path from 'path'
function toSafeBasename(filename: unknown): string {
return path.basename(typeof filename === 'string' ? filename : '').trim()
} Type guard
function isSafeBasename(filename: string): boolean {
return filename === path.basename(filename) && !/[\\/\x00-\x1f]/.test(filename) && !filename.includes('..')
} Try / catch
if (isUnsafeFilePath(filename)) {
throw new Error(`Invalid filename: unsafe characters or path traversal attempt detected in filename "${filename}"`)
} Prevention
- Always coerce to path.basename() before validation.
- Never interpolate user-supplied filenames into filesystem paths without re-validating the resolved path.
- Run security tests with traversal payloads (../, %2e%2e, ..%2f, null byte) against the validator.
When it happens
Trigger: Uploader sends filename='../../etc/passwd' or '..%2f..%2fconfig'; filename contains a null byte ('file.txt\0.exe'); filename is an absolute path ('/tmp/x') or Windows drive path ('C:\x'); control characters embedded in the name.
Common situations: Malicious upload attempting directory traversal; client that sends full original paths instead of basenames; URL-encoded names not decoded before validation; legacy integration that legitimately uses subpaths (now rejected by design).
Related errors
- Invalid or unsafe fileName detected
- Invalid filename after sanitization
- Invalid path characters detected
- Invalid filename: filename is required and must be a string
- Invalid MIME type: MIME type is required and must be a strin
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/b930b9ef72aa487f.
Report an issue: GitHub.