Root cause
Authentication & access control introduced
The scope helper hashes complete credentials but returns an empty scope when either connection field is absent.
How AI contributed: Direct introductionPublished Jul 14, 2026 in
czlonkowski/n8n-mcpAll 11 findings in this repository
Provisional finding. Full causal and release verification remains incomplete.
Root cause
The scope helper hashes complete credentials but returns an empty scope when either connection field is absent.
Fix
The handler refuses multi-tenant requests that resolve to the empty storage scope.
Case facts
@@ -205,1 +217,16 @@+ * those deployments share a single logical tenant.+ *+ * Must be deterministic across processes and restarts: this id is persisted+ * in the database and compared on later reads/deletes. Do NOT use+ * createCacheKey() from cache-utils, which uses a per-process random salt.+ */+export function getInstanceScopeId(context?: InstanceContext): string {+ if (context?.n8nApiUrl && context?.n8nApiKey) {+ const url = context.n8nApiUrl.trim().replace(/\/+$/, '').toLowerCase();+ return createHash('sha256')+ .update(`n8n-mcp-wv:${url}:${context.n8nApiKey}`)+ .digest('hex')+ .slice(0, 32);+ }+ return ''; }@@ -2405,8 +2405,18 @@ ): Promise<McpToolResponse> { try { const input = workflowVersionsSchema.parse(args);++ // SECURITY (GHSA-2cf7-hpwf-47h9): multi-tenant requests must resolve a+ // complete tenant scope; fail closed otherwise.+ if (process.env.ENABLE_MULTI_TENANT === 'true' && getInstanceScopeId(context) === '') {+ return {+ success: false,+ error: 'Workflow version storage is not available for this tenant context'+ };+ }+ const client = context ? getN8nApiClient(context) : null; const versioningService = new WorkflowVersioningService(repository, client || undefined, getInstanceScopeId(context)); switch (input.mode) { case 'list': {AI-assisted change b448851a5827e4a9f1094601a505afa71529650c65b23ccbfb595d9e3bba195f · Fix 925bebe96a8ad6bc9fcb26d1796134ac38290583aea0a347ee054f1cc67ca9db