{"record":{"id":"5b7825f4e34af49c","repo":"FlowiseAI/Flowise","slug":"custom-mcp-script-path-not-in-allowed-list","errorCode":null,"errorMessage":"Custom MCP script path not in allowed list.","messagePattern":"Custom MCP script path not in allowed list\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/tools/MCP/core.ts","lineNumber":259,"sourceCode":"            name: name,\n            description: description,\n            schema: argsSchema\n        }\n    )\n}\n\nexport const validateArgsForLocalFileAccess = (args: string[]): void => {\n    const allowedScriptPaths = (process.env.CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS ?? '')\n        .split(',')\n        .map((s) => s.trim())\n        .filter(Boolean)\n\n    const scriptArg = args[0]\n\n    if (allowedScriptPaths.length === 0)\n        throw new Error('Custom MCP script execution disabled. Configure CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS environment variable.')\n\n    if (!allowedScriptPaths.includes(scriptArg)) throw new Error('Custom MCP script path not in allowed list.')\n}\n\nexport const validateCommandInjection = (args: string[]): void => {\n    const dangerousPatterns = [\n        // Shell metacharacters\n        /[;&|`$(){}[\\]<>]/,\n        // Command chaining\n        /&&|\\|\\||;;/,\n        // Redirections\n        />>|<<|>/,\n        // Backticks and command substitution\n        /`|\\$\\(/,\n        // Process substitution\n        /<\\(|>\\(/\n    ]\n\n    for (const arg of args) {\n        if (typeof arg !== 'string') continue","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/tools/MCP/core.ts#L241-L277","documentation":"Thrown by validateArgsForLocalFileAccess when CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS is non-empty but the first argument (args[0], treated as the script path) is not present in the allow-list. The check is a strict equality membership test, so path normalization mismatches fail it.","triggerScenarios":"args[0] is a path that differs from every entry in the allow-list: relative vs absolute, symlink, trailing slash, case difference on case-sensitive filesystems, or simply a different file.","commonSituations":"Operator allow-listed /opt/mcp/server.js but node passes ./server.js or /opt/mcp/server.js/; package path resolved differently across deploys; copy-paste typo in the env var.","solutions":["Make args[0] an absolute path identical to an allow-list entry (same resolution, no trailing slash).","Add the exact path being passed (print it once to compare) to CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS.","Resolve symlinks/relative segments on both sides so the strings match byte-for-byte."],"exampleFix":"// before: args[0] = './server.js', allow-list = /opt/mcp/server.js\n\n// after: pass the same absolute path\nconst scriptPath = path.resolve('/opt/mcp/server.js')\nconst serverParams = { command: 'node', args: [scriptPath] }","handlingStrategy":"validation","validationCode":"const allowed = (process.env.CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS ?? '').split(',').map(s => s.trim()).filter(Boolean)\nconst scriptArg = path.resolve(args[0])\nif (!allowed.includes(scriptArg)) {\n  throw new Error(`Script path ${scriptArg} not in allow-list. Add it to CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS`)\n}","typeGuard":"const scriptPathAllowed = (scriptPath: string): boolean => {\n  const allowed = (process.env.CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS ?? '').split(',').map(s => s.trim()).filter(Boolean)\n  return allowed.includes(path.resolve(scriptPath))\n}","tryCatchPattern":"try {\n  validateArgsForLocalFileAccess(args)\n} catch (e) {\n  if (e.message === 'Custom MCP script path not in allowed list.') {\n    // resolve args[0] to absolute and compare to allow-list entries\n  }\n  throw e\n}","preventionTips":["Always resolve script paths to absolute form before they reach the validator.","Keep the allow-list and the actual deploy path in sync (same symlinks, no trailing slashes).","Add a startup diff that warns if a configured script node's path is missing from the allow-list."],"tags":["mcp","security","allow-list","paths"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}