fix: allow absolute folder paths in Docker via FLOWISE_ALLOWED_FOLDER_PATHS#6315
fix: allow absolute folder paths in Docker via FLOWISE_ALLOWED_FOLDER_PATHS#6315deepak0x wants to merge 1 commit intoFlowiseAI:mainfrom
Conversation
…_PATHS Closes FlowiseAI#5958 isPathTraversal() blocked all absolute Unix paths (/^\//). This made the Folder with Files document loader unusable in Docker where users mount volumes at absolute paths like /data/documents. The existing escape hatch (PATH_TRAVERSAL_SAFETY=false) disables ALL traversal safety, which is too broad for operators who only need to grant access to specific mount points. This fix adds a targeted FLOWISE_ALLOWED_FOLDER_PATHS env var: FLOWISE_ALLOWED_FOLDER_PATHS=/data/documents,/mnt/shared When set, absolute Unix paths within one of those base directories pass through isPathTraversal() without triggering the block. All other checks (../ traversal, encoded chars, UNC/Windows paths, null bytes) remain fully enforced. Changes: validator.ts — getAllowedFolderPaths() helper + updated isPathTraversal() validator.test.ts — 8 new test cases covering the env var behaviour docker/.env.example, packages/server/.env.example — documented
There was a problem hiding this comment.
Code Review
This pull request introduces the FLOWISE_ALLOWED_FOLDER_PATHS environment variable, allowing users to specify absolute Unix paths that should bypass path traversal checks. This provides a more granular security configuration compared to disabling traversal safety entirely. The changes include updates to the validator logic, environment variable examples, and comprehensive test cases. Feedback was provided regarding a potential logic failure when the root directory is allowed and the efficiency of parsing environment variables on every request, suggesting a caching mechanism.
| const isExplicitlyAllowed = allowedPaths.some( | ||
| (allowed) => normalizedInput === allowed || normalizedInput.startsWith(allowed + path.sep) | ||
| ) |
There was a problem hiding this comment.
The current logic for checking subdirectories fails when the allowed path is the root directory (/). If allowed is /, allowed + path.sep becomes // (on Unix), and normalizedInput.startsWith('//') will be false for standard absolute paths like /etc/passwd. A more robust check for the root path is needed.
const isExplicitlyAllowed = allowedPaths.some((allowed) => {
if (normalizedInput === allowed) return true
const prefix = allowed === path.sep ? allowed : allowed + path.sep
return normalizedInput.startsWith(prefix)
})| const getAllowedFolderPaths = (): string[] => { | ||
| const raw = process.env.FLOWISE_ALLOWED_FOLDER_PATHS | ||
| if (!raw) return [] | ||
| return raw | ||
| .split(',') | ||
| .map((p) => p.trim()) | ||
| .filter((p) => p !== '' && path.isAbsolute(p)) | ||
| .map((p) => { | ||
| const normalized = path.normalize(p) | ||
| // Strip trailing separator so startsWith checks work correctly, | ||
| // but never strip the root '/' itself. | ||
| return normalized.length > 1 && normalized.endsWith(path.sep) ? normalized.slice(0, -1) : normalized | ||
| }) | ||
| } |
There was a problem hiding this comment.
The getAllowedFolderPaths function is called every time isPathTraversal encounters an absolute path. Since environment variables are typically static during the application's lifecycle, parsing the string, splitting, and normalizing paths on every call is inefficient. Consider caching the result.
const getAllowedFolderPaths = (() => {
let cache: { raw: string | undefined; paths: string[] } | null = null
return (): string[] => {
const raw = process.env.FLOWISE_ALLOWED_FOLDER_PATHS
if (cache && cache.raw === raw) return cache.paths
const paths = (raw || '')
.split(',')
.map((p) => p.trim())
.filter((p) => p !== '' && path.isAbsolute(p))
.map((p) => {
const normalized = path.normalize(p)
return normalized.length > 1 && normalized.endsWith(path.sep) ? normalized.slice(0, -1) : normalized
})
cache = { raw, paths }
return paths
}
})()|
@HenryHengZJ ready for review. |
Closes #5958
Problem
The
isPathTraversal()validator blocks all absolute Unix paths (regex/^\//). This makes the Folder with Files document loader unusable in Docker, where users mount volumes at paths like/data/documents.The existing escape hatch
PATH_TRAVERSAL_SAFETY=falsedisables all traversal safety — too broad for operators who only want to allow specific mount points.Fix
A new
FLOWISE_ALLOWED_FOLDER_PATHSenv var accepts a comma-separated list of trusted absolute base paths:Absolute Unix paths that fall within one of those base directories pass through
isPathTraversal()without triggering the block. All other checks (../traversal, percent-encoded chars, UNC/Windows paths, null bytes) remain fully enforced.What's unchanged
FLOWISE_ALLOWED_FOLDER_PATHSis setPATH_TRAVERSAL_SAFETY=falsestill disables all checks (existing escape hatch preserved)../and encoded traversal through an allowed path (/data/docs/../../../etc) is still caughtFiles changed
packages/components/src/validator.ts—getAllowedFolderPaths()helper + updatedisPathTraversal()packages/components/src/validator.test.ts— 8 new test casesdocker/.env.example+packages/server/.env.example— documented the new var next toPATH_TRAVERSAL_SAFETY