FlowiseAI/Flowise · critical · Error
Invalid file path: null byte detected in "${key}"
Error message
Invalid file path: null byte detected in "${key}" What it means
Thrown by getSafeFilePath() after percent-decoding the key, when the decoded value contains a NUL byte (\0). Null-byte injection is a classic technique to truncate a path or filename at the OS/C level so that a check sees one value but the syscall uses another; getSafeFilePath decodes first (so encoded %00 is caught too) and rejects the request outright rather than attempting to clean it.
Source
Thrown at packages/components/src/validator.ts:457
* @param {string} baseDir The trusted base directory (e.g. a freshly created temp dir)
* @param {string} key The untrusted relative key or filename
* @returns {string} A validated absolute path guaranteed to be within baseDir
* @throws {Error} If key is missing/invalid or the resolved path escapes baseDir
*/
export const getSafeFilePath = (baseDir: string, key: string): string => {
if (!key || typeof key !== 'string') {
throw new Error('Invalid file path: key is required and must be a string')
}
let decodedKey = key
try {
decodedKey = decodeURIComponent(key)
} catch {
// malformed percent-encoding — keep the raw key; resolve/relative handle it safely
}
if (decodedKey.includes('\0')) {
throw new Error(`Invalid file path: null byte detected in "${key}"`)
}
const resolvedBase = path.resolve(baseDir)
const resolvedPath = path.resolve(resolvedBase, decodedKey)
if (process.env.PATH_TRAVERSAL_SAFETY === 'false') {
return resolvedPath
}
const relative = path.relative(resolvedBase, resolvedPath)
if (relative === '' || relative === '..' || relative.startsWith('..' + path.sep) || path.isAbsolute(relative)) {
throw new Error(`Invalid file path: path traversal attempt detected in "${key}"`)
}
return resolvedPath
}
View on GitHub (pinned to abe4a8601a)
Solutions
- Treat the request as malicious: reject with 400 and log the source IP / request id for investigation.
- Ensure the key never carries binary/null data by validating the input charset (printable ASCII / UTF-8) at the request boundary.
- Do not attempt to strip the null byte and continue — the presence itself indicates an attack; reject the whole request.
Example fix
// before
const abs = getSafeFilePath(baseDir, key) // throws on %00
// after
if (key.includes('\0') || /%00/i.test(key)) {
logger.warn('Null-byte injection attempt blocked', { key, ip: req.ip })
return res.status(400).json({ message: 'Invalid key' })
}
const abs = getSafeFilePath(baseDir, key) Defensive patterns
Strategy: validation
Validate before calling
// Reject null bytes in either raw or encoded form before resolving
if (typeof key !== 'string' || key.includes('\0') || /%00/i.test(key)) {
logger.warn('Null-byte key blocked', { key, ip: req.ip })
return res.status(400).json({ message: 'Invalid key' })
} Type guard
const hasNoNullByte = (v: unknown): v is string =>
typeof v === 'string' && !v.includes('\0') && !/%00/i.test(v) Try / catch
try {
const abs = getSafeFilePath(baseDir, key)
} catch (e) {
// null-byte presence is an attack — reject and log, never strip-and-retry
return res.status(400).json({ message: 'Invalid file path' })
} Prevention
- Validate input charset (printable UTF-8) at the trust boundary.
- Treat any null byte as malicious and log the request origin.
- Never strip null bytes and continue — reject the whole request.
When it happens
Trigger: A key containing a literal \0; a key containing `%00` which decodes to \0 via decodeURIComponent; a key like `legit.txt%00.exe` intended to bypass extension checks. Reached when a client (or an attacker) supplies a URL-encoded null byte in a path/query param that flows into getSafeFilePath.
Common situations: Security scanning / fuzzing of file endpoints; legacy clients that include binary data in keys; a proxy that double-encodes the path. This is almost always indicative of a malicious or malformed request, not a normal user error.
Related errors
- Invalid or unsafe file name: ${name}
- Invalid file path: key is required and must be a string
- Invalid file path: path traversal attempt detected in "${key
- Failed to parse Supabase filter: ${error.message}
- Disallowed method: ${method}
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/75996220c63ff3df.
Report an issue: GitHub.