{"record":{"id":"223edbbfcb0f9ad7","repo":"FlowiseAI/Flowise","slug":"invalid-sqlite-path-path-must-be-within-allowed-d","errorCode":null,"errorMessage":"Invalid SQLite path: path must be within allowed directories (${allowedDirs.join(', ')}). Attempted path: ${resolvedPath}","messagePattern":"Invalid SQLite path: path must be within allowed directories \\((.+?)\\)\\. Attempted path: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/src/validator.ts","lineNumber":353,"sourceCode":"\n    const basePath = userProvidedPath.trim()\n\n    if (basePath.includes('..')) throw new Error('Invalid SQLite path: path traversal attempt detected')\n    if (basePath.toLowerCase().includes('%2e') || basePath.toLowerCase().includes('%2f') || basePath.toLowerCase().includes('%5c'))\n        throw new Error('Invalid SQLite path: encoded path traversal attempt detected')\n    // eslint-disable-next-line no-control-regex\n    if (/\\0/.test(basePath) || /[\\x00-\\x1f]/.test(basePath))\n        throw new Error('Invalid SQLite path: null bytes or control characters detected')\n    if (/^[a-zA-Z]:\\\\/.test(basePath)) throw new Error('Invalid SQLite path: Windows absolute paths are not allowed')\n    if (/^\\\\\\\\[^\\\\]/.test(basePath)) throw new Error('Invalid SQLite path: UNC paths are not allowed')\n    if (/^\\\\\\\\\\?\\\\/.test(basePath)) throw new Error('Invalid SQLite path: extended-length paths are not allowed')\n\n    const resolvedPath = path.isAbsolute(basePath) ? path.resolve(basePath) : path.resolve(path.join(defaultDir, basePath))\n\n    if (resolvedPath.includes('..')) throw new Error('Invalid SQLite path: path traversal detected in resolved path')\n\n    if (!isPathWithinAllowedSQLiteDirs(resolvedPath, allowedDirs)) {\n        throw new Error(\n            `Invalid SQLite path: path must be within allowed directories (${allowedDirs.join(', ')}). Attempted path: ${resolvedPath}`\n        )\n    }\n\n    return resolvedPath\n}\n\n/**\n * Restricts SQL executed against a SQLite database opened via validateSQLitePath to a\n * single read-only SELECT/WITH statement.\n *\n * The Sql Database Chain hands LLM-generated SQL directly to TypeORM's raw query\n * executor with no statement-type filtering. Without this guard, a compromised or\n * malicious LLM response can run `ATTACH DATABASE`/`VACUUM INTO`/bare `PRAGMA` to write\n * arbitrary files anywhere the process can write, bypassing validateSQLitePath (which\n * only constrains the initial connection path, not queries run afterward).\n *\n * All legitimate queries issued against sqlite by this chain (including langchain's own","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/src/validator.ts#L335-L371","documentation":"Thrown by validateSQLitePath (packages/components/src/validator.ts:353) when the resolved absolute path is not inside any allowed base directory. Allowed dirs are ~/.flowise plus DATABASE_PATH (if set). The message names the allowed dirs and the attempted path.","triggerScenarios":"Database Path resolves outside ~/.flowise (and outside DATABASE_PATH when unset), e.g. '/var/lib/flowise.db', '/tmp/x.sqlite', or a relative path that escapes via a symlink.","commonSituations":"Wanting the DB on a separate volume; Docker mounts outside the default dir; production deployments needing a custom data dir; HOME pointing somewhere unexpected.","solutions":["Set DATABASE_PATH=/your/data/dir and place the file inside it.","Use a relative filename to resolve automatically under ~/.flowise.","Confirm HOME / USERPROFILE is set correctly — getUserHome() drives the allow-list root.","Symlink the target dir into ~/.flowise and use a relative filename."],"exampleFix":"// before\nprocess.env.DATABASE_PATH = ''\nnodeParams.databasePath = '/mnt/data/app.db'\n\n// after\nprocess.env.DATABASE_PATH = '/mnt/data'\nnodeParams.databasePath = '/mnt/data/app.db'   // inside allow-list","handlingStrategy":"validation","validationCode":"const { resolve, join } = require('path');\nconst allowed = [join(require('os').homedir(), '.flowise')];\nif (process.env.DATABASE_PATH) allowed.push(resolve(process.env.DATABASE_PATH));\nconst r = resolve(databasePath);\nif (!allowed.some((d) => r === d || r.startsWith(d + require('path').sep))) throw new Error('DB path outside allow-list: ' + r);","typeGuard":"const isWithinAllowed = (p: string, allowed: string[]): p is string => allowed.some((d) => p === d || p.startsWith(d + '/'));","tryCatchPattern":"try { validateSQLitePath(databasePath) } catch (e) { if (e instanceof Error && /within allowed directories/.test(e.message)) { throw new Error('set DATABASE_PATH or move DB under ~/.flowise') } else throw e }","preventionTips":["Set DATABASE_PATH when the DB must live outside ~/.flowise.","Verify HOME/USERPROFILE is correct.","Use plain filenames so resolution lands under the default dir."],"tags":["path-traversal","security","validation","filesystem","configuration","env","sqlite","database","flowise"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}