{"record":{"id":"ad67124ad68f11eb","repo":"FlowiseAI/Flowise","slug":"invalid-sqlite-path-path-traversal-detected-in-re","errorCode":null,"errorMessage":"Invalid SQLite path: path traversal detected in resolved path","messagePattern":"Invalid SQLite path: path traversal detected in resolved path","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/components/src/validator.ts","lineNumber":350,"sourceCode":"    if (!userProvidedPath || userProvidedPath.trim() === '') {\n        throw new Error('Invalid SQLite path: database path is required')\n    }\n\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","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/src/validator.ts#L332-L368","documentation":"Thrown by validateSQLitePath (packages/components/src/validator.ts:350) when the resolved absolute path still contains '..' after path.resolve(). path.resolve normally collapses '..', so hitting this branch means an unusual absolute-path shape slipped past the earlier substring check.","triggerScenarios":"An absolute path that path.resolve does not fully normalize — rare; typically a hand-assembled or edge-case absolute path.","commonSituations":"Programmatic path concatenation; platform-specific quirks; effectively an internal safety net rather than a routine config error.","solutions":["Run path.normalize() on the candidate path before passing it in.","Build the path from trusted segments rather than string concatenation.","Use a relative filename so it resolves cleanly under ~/.flowise."],"exampleFix":"// before\nnodeParams.databasePath = concatAbsPath   // residual '..'\n\n// after\nconst { path } = require('path')\nnodeParams.databasePath = path.normalize(concatAbsPath)","handlingStrategy":"validation","validationCode":"const { normalize } = require('path');\nconst candidate = normalize(String(databasePath ?? ''));\nif (candidate.includes('..')) throw new Error('DB path still contains .. after normalize');","typeGuard":"const isNormalized = (p: unknown): p is string => typeof p === 'string' && !normalize(p).includes('..');","tryCatchPattern":"try { validateSQLitePath(databasePath) } catch (e) { if (e instanceof Error && /resolved path/.test(e.message)) { databasePath = normalize(databasePath) } else throw e }","preventionTips":["path.normalize() DB paths before submission.","Build paths with path.join, not string concatenation.","Use plain filenames to avoid the absolute-path edge branch."],"tags":["path-traversal","security","validation","filesystem","edge-case","sqlite","database","flowise"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}