FlowiseAI/Flowise · error · Error
Invalid filename after sanitization
Error message
Invalid filename after sanitization
What it means
Second guard in sanitizeFilename, run after the `sanitize()` library call and after stripping leading dots. It catches filenames that became empty or still contain a path separator after sanitization — i.e. inputs that survived the first check but are still unsafe to use as a single path component.
Source
Thrown at packages/components/src/storage/BaseStorageProvider.ts:54
abstract removeSpecificFileFromUpload(filePath: string): Promise<void>
abstract removeSpecificFileFromStorage(...paths: string[]): Promise<StorageSizeResult>
abstract removeFolderFromStorage(...paths: string[]): Promise<StorageSizeResult>
abstract getStorageSize(orgId: string): Promise<number>
abstract getMulterStorage(): any
abstract getLoggerTransports(logType: 'server' | 'error' | 'requests' | 'audit', config?: any): any[]
/**
* Shared utility for sanitizing filenames to prevent path traversal and other issues
*/
protected sanitizeFilename(filename: string): string {
if (!filename || isUnsafeFilePath(filename)) {
throw new Error('Invalid or unsafe fileName detected')
}
const sanitizedFilename = sanitize(filename)
// Remove leading dots to prevent hidden files or relative path jumps
const cleaned = sanitizedFilename.replace(/^\.+/, '')
if (!cleaned || cleaned.includes('/') || cleaned.includes('\\')) {
throw new Error('Invalid filename after sanitization')
}
return cleaned
}
/**
* Shared utility for getting the base storage path
*/
protected getStoragePath(): string {
const storagePath = process.env.BLOB_STORAGE_PATH
? path.join(process.env.BLOB_STORAGE_PATH)
: path.join(getUserHome(), '.flowise', 'storage')
if (!fs.existsSync(storagePath)) {
fs.mkdirSync(storagePath, { recursive: true })
}
return storagePath
}
View on GitHub (pinned to abe4a8601a)
Solutions
- Validate that the caller-supplied filename yields a non-empty basename with no separators before invoking storage.
- Fall back to a generated safe name (e.g. a UUID) when the sanitized result is empty.
- Treat this as an attack signal and log/reject the request upstream.
Example fix
// before const name = '....' // after const name = sanitizeUserFileName(fileName) || crypto.randomUUID()
Defensive patterns
Strategy: validation
Validate before calling
import sanitize from 'sanitize-filename'
function safeFilenameOrUuid(filename: string, fallback: string): string {
const cleaned = sanitize(filename).replace(/^(\.+)/, '')
if (!cleaned || cleaned.includes('/') || cleaned.includes('\\')) return fallback
return cleaned
} Type guard
function isNonEmptySanitized(name: string): boolean {
const c = name.replace(/^(\.+)/, '')
return c.length > 0 && !c.includes('/') && !c.includes('\\')
} Try / catch
try {
await provider.streamStorageFile(chatflowId, chatId, fileName, orgId)
} catch (e) {
if (/after sanitization/.test(e.message)) return res.status(400).send('invalid filename')
throw e
} Prevention
- Reject filenames that reduce to empty after sanitization.
- Fall back to a UUID filename when sanitization yields nothing.
- Treat repeated empty-after-sanitize inputs as abusive.
When it happens
Trigger: A filename composed entirely of dot/special characters that sanitize() reduces to an empty string, or an input whose sanitized form still contains `/` or `\`. The guard is `!cleaned || cleaned.includes('/') || cleaned.includes('\\')` at BaseStorageProvider.ts:53.
Common situations: Filenames like `....`, `...//`, or strings of only forbidden characters; locale/encoding edge cases that defeat the sanitizer.
Related errors
- Invalid or unsafe fileName detected
- Invalid path characters detected
- Invalid chatflowId format - must be a valid UUID
- Invalid filename: unsafe characters or path traversal attemp
- Invalid path: path traversal attempt detected
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/bb5de0f313277e30.
Report an issue: GitHub.