title: MCP Tool Sequential Integer ID Enumeration (Cross-Tenant IDOR, CVE-2026-54052)
id: ATR-2026-02406
rule_version: 1
status: experimental
description: |
  Detects sequential integer ID enumeration against MCP tools that expose auto-increment database row identifiers without tenant scoping — an Insecure Direct Object Reference (IDOR / BOLA) that lets one tenant read or destroy another tenant's data by counting upward through the ID space. Anchored on CVE-2026-54052 (CVSS 9.6, n8n-mcp before v2.56.1): the `workflow_versions` SQLite table carried no tenant column and the `n8n_workflow_versions` tool never checked ownership, so an attacker on a multi-tenant HTTP deployment (`ENABLE_MULTI_TENANT=true`) could walk `versionId` incrementally and pull other tenants' full workflow snapshots — node definitions, API keys and bearer tokens — and delete their backups. Generalised beyond n8n to any MCP tool whose version/backup/snapshot/revision resource is addressed by a bare integer. Detection covers (a) an MCP tool call whose integer ID argument is bound to a counter variable rather than a literal, (b) a burst of repeated calls to the same versioned-resource tool carrying distinct numeric IDs, (c) a generalised burst of version/backup ID parameters in one exchange window, (d) an iteration construct driving a version/backup ID parameter in agent or client code, (e) a shell/HTTP enumeration loop aimed at an MCP endpoint, (f) a deployment pinned to a vulnerable n8n-mcp release with multi-tenancy enabled, and (g) skill or instruction content that weaponises cross-tenant ID walking for credential harvest. CWE-639 (Authorization Bypass Through User-Controlled Key), CWE-284 (Improper Access Control), CWE-522 (Insufficiently Protected Credentials).
author: ATR Community
date: 2026/07/28
schema_version: '0.1'
detection_tier: pattern
maturity: test
severity: critical
references:
  owasp_llm:
    - LLM02:2025
    - LLM06:2025
  owasp_agentic:
    - ASI03:2026
    - ASI02:2026
  mitre_atlas:
    - AML.T0057 - LLM Data Leakage
    - AML.T0053 - AI Agent Tool Invocation
    - AML.T0024 - Exfiltration via AI Inference API
  mitre_attack:
    - T1213 - Data from Information Repositories
    - T1119 - Automated Collection
    - 'T1552.001 - Unsecured Credentials: Credentials In Files'
  cve:
    - CVE-2026-54052
  cwe:
    - CWE-639
    - CWE-284
    - CWE-522
  external:
    - https://www.manifold.security/blog/n8n-mcp-idor-cross-tenant-credential-theft
metadata_provenance:
  mitre_atlas: human-reviewed
  owasp_llm: human-reviewed
  owasp_agentic: human-reviewed
  cve: human-reviewed
  cwe: human-reviewed
  external: human-reviewed
compliance:
  eu_ai_act:
    - article: '15'
      context: 'An MCP tool that addresses tenant-owned records by unscoped auto-increment integer breaks the accuracy and cybersecurity duty of Article 15: identical tool input from any tenant returns any other tenant''s data. Detecting integer-walk enumeration at the tool boundary is the runtime control that keeps a shared AI tool server from serving cross-tenant records.'
      strength: primary
    - article: '10'
      context: Article 10 data governance requires that training and operational data stay within its authorised tenancy. Sequential-ID enumeration of workflow version snapshots pulls another tenant's node definitions and embedded credentials into the calling agent's context window, contaminating that agent's operational data with data it has no lawful basis to hold.
      strength: secondary
  nist_ai_rmf:
    - function: Manage
      subcategory: MG.2.3
      context: Blocking or alerting on a burst of integer-incremented ID arguments to a versioned-resource MCP tool is the primary risk treatment for CVE-2026-54052-class IDOR; treatment must sit at the tool-invocation boundary because the vulnerable server performs no ownership check of its own.
      strength: primary
    - function: Map
      subcategory: MP.5.1
      context: Any MCP tool that exposes database row identifiers directly to agent-controlled arguments must be catalogued as a cross-tenant impact surface in the AI risk register, with the blast radius recorded as every tenant sharing the deployment rather than only the calling tenant.
      strength: primary
    - function: Measure
      subcategory: MS.2.7
      context: MEASURE 2.7 (security and resilience evaluated and documented) is supported by measuring how many distinct integer IDs a single agent session requests from one versioned-resource tool per time window, which is the observable that separates authorised version retrieval from enumeration.
      strength: secondary
    - function: Govern
      subcategory: GV.6.1
      context: Supplier assessment of third-party MCP servers under GV.6.1 must confirm that every tenant-scoped resource is addressed by an unguessable or ownership-checked identifier before the server is admitted to a shared agent deployment.
      strength: secondary
  iso_42001:
    - clause: '8.1'
      context: 'Operational planning and control must gate MCP tools that accept raw integer record identifiers: either disable the tool in multi-tenant deployments (for CVE-2026-54052, DISABLED_TOOLS=n8n_workflow_versions) or require the server to scope every query by tenant before agent traffic is permitted.'
      strength: primary
    - clause: '8.3'
      context: Clause 8.3 AI risk treatment is implemented here by runtime detection of cross-tenant object-reference enumeration, complementing the vendor patch that added an instance_id column so version queries are scoped to the calling tenant.
      strength: secondary
tags:
  category: context-exfiltration
  subcategory: cross-tenant-idor-id-enumeration
  scan_target: both
  confidence: high
  source: cve-disclosure
  vendor_sources: n8n-mcp-cve-2026-54052
agent_source:
  type: mcp_exchange
  framework:
    - n8n-mcp
    - any
  provider:
    - any
detection:
  condition: any
  method: pattern
  false_positives:
    - Migration, backup-verification or disaster-recovery tooling that legitimately walks every version row of a single-tenant deployment — the payload shape is identical to the attack and only the authorisation context differs.
    - Integration or load tests that seed and then read back N sequential version records against a test instance.
    - 'An agent that legitimately fetches each version returned by a prior authorised list call still emits one invocation envelope per ID, so layers 2 and 3 fire: they count ID-bearing calls and cannot tell a server-supplied ID set from a guessed one. (A returned collection on its own no longer matches — layer 3 requires a per-ID invocation envelope — but an authorised fan-out of real calls is indistinguishable from a sweep.)'
    - 'Security research and advisory prose that quotes an attacker''s instruction verbatim can still match layer 7. Purely descriptive write-ups no longer match: layer 7 additionally requires a collection or exfiltration imperative, which describing text (''an attacker could read the api key'') does not carry.'
    - Single-tenant deployments pinned below v2.56.1 that set ENABLE_MULTI_TENANT=true for local development against one instance will match layer 6 even though no second tenant exists.
  conditions:
    - field: content
      operator: regex
      value: (?i)n8n_workflow_versions[\s\S]{0,240}[\\"']{0,3}version_?id[\\"']{0,3}\s*[:=]\s*(?:\$\{[a-z_][a-z0-9_]{0,12}\}|\$[a-z_][a-z0-9_]{0,12}(?:[^a-z0-9_.]|$)|\{\{?[a-z_][a-z0-9_]{0,12}\}\}?|%[ds]|(?:i|j|k|n|m|idx|index|counter|cnt|ctr|seq|num|offset|start)(?:[^a-z0-9_.]|$)|[a-z_][a-z0-9_]{0,12}\s*\+\s*\d{1,6}|[a-z_][a-z0-9_]{0,12}\+\+)
      description: 'CVE-2026-54052 direct exploitation: n8n_workflow_versions invoked with versionId bound to a loop counter, interpolation or increment expression instead of a fixed version the caller was authorised to see'
    - field: content
      operator: regex
      value: (?i)(?:n8n_workflow_versions[\s\S]{0,200}?[\\"']{1,3}version_?id[\\"']{1,3}\s*:\s*[\\"']{0,3}\d{1,9}[\s\S]{0,200}?){3,}
      description: Three or more n8n_workflow_versions invocations with numeric versionId inside a single MCP exchange or trace window — the CVE-2026-54052 cross-tenant snapshot sweep
    - field: content
      operator: regex
      value: (?i)(?:(?:tools?[/_]call|call_?tool|jsonrpc|[\\"']{0,3}(?:method|arguments|params)[\\"']{0,3}\s*:|\binvoke)[\s\S]{0,200}?[\\"']{1,3}(?:version_?id|backup_?id|snapshot_?id|revision_?id|archive_?id|export_?id|dump_?id|restore_?id)[\\"']{1,3}\s*:\s*[\\"']{0,3}\d{1,9}[\s\S]{0,200}?){4,}
      description: Four or more integer version/backup/snapshot identifiers each carried inside its own tool-invocation envelope in one exchange window — enumeration of a backup resource addressed by auto-increment row id
    - field: content
      operator: regex
      value: (?i)(?:for\s*\(|for\s+[a-z_][a-z0-9_]{0,16}\s+in\s|while\s*\(|foreach\s*\(|range\s*\(\s*\d{1,7}\s*,)[\s\S]{0,200}(?:call_?tool|tools?[/_]call|jsonrpc|\bmcp\b|client\.[a-z_]{1,20}|session\.[a-z_]{1,20}|fetch\s*\(|axios|requests?\.(?:get|post)|curl\s)[\s\S]{0,200}[\\"']{0,3}(?:version_?id|backup_?id|snapshot_?id|revision_?id|archive_?id|export_?id|record_?id|object_?id|entry_?id|row_?id)[\\"']{0,3}\s*[:=]\s*(?:\$\{[a-z_][a-z0-9_]{0,12}\}|\$[a-z_][a-z0-9_]{0,12}(?:[^a-z0-9_.]|$)|\{\{?[a-z_][a-z0-9_]{0,12}\}\}?|%[ds]|(?:i|j|k|n|m|idx|index|counter|cnt|ctr|seq|num|offset|cur|start)(?:[^a-z0-9_.]|$)|[a-z_][a-z0-9_]{0,12}\s*\+\s*\d{1,6})
      description: Loop or range construct feeding an incrementing counter into a version/backup/record ID argument of a remote tool call — programmatic object-reference enumeration in agent or client code
    - field: content
      operator: regex
      value: (?i)(?:\$\(seq\s|`seq\s|seq\s+\d{1,7}\s+\d{2,9}|\{\d{1,7}\.\.\d{2,9}\}|range\s*\(\s*\d{1,7}\s*,\s*\d{2,9})[\s\S]{0,400}(?:/mcp\b|jsonrpc|calltool|call_tool|tools_call)[\s\S]{0,400}(?:version_?id|backup_?id|snapshot_?id|revision_?id|record_?id)[\\"']{0,3}\s*[:=]\s*[\\"']{0,3}(?:\$\{?[a-z_]|\{[a-z_]|%[ds])
      description: Shell or scripted request loop iterating a numeric sequence against an MCP endpoint with the counter substituted into a record ID field — direct cross-tenant harvesting run
    - field: content
      operator: regex
      value: (?i)(?:n8n[-_]mcp["'\s:@=^~>v]{1,8}(?:2\.(?:5[0-5]|[1-4][0-9]|[0-9])\.\d{1,3}|2\.56\.0)[\s\S]{0,800}enable_multi_tenant\s*[:=]\s*["']?\s*true|enable_multi_tenant\s*[:=]\s*["']?\s*true[\s\S]{0,800}n8n[-_]mcp["'\s:@=^~>v]{1,8}(?:2\.(?:5[0-5]|[1-4][0-9]|[0-9])\.\d{1,3}|2\.56\.0))
      description: Deployment manifest pins n8n-mcp below the v2.56.1 fix while enabling multi-tenant HTTP mode — the exact precondition CVE-2026-54052 requires for cross-tenant workflow snapshot theft
    - field: content
      operator: regex
      value: (?i)(?:iterat\w{0,4}|increment\w{0,4}|enumerat\w{0,4}|brute[\s_-]?forc\w{0,3}|loop\s+(?:over|through)|walk\s+(?:the\s+)?(?:ids?|range)|count\s+up\s+through)[\s\S]{0,200}(?:version_?id|backup_?id|snapshot_?id|record_?id|integer\s+ids?|sequential\s+ids?|workflow[\s_-]?versions?)[\s\S]{0,240}(?:other|another|every|all|each|cross)[\s_-]?(?:tenant|customer|organi[sz]ation|account|workspace|instance)[\s\S]{0,240}(?:extract|harvest|collect|exfiltrat\w{0,3}|siphon|scrape|steal|dump|capture|save|send|post|upload|report\s+back|write\s+(?:them|it|these))[\s\S]{0,160}(?:credential|api[\s_-]?key|bearer|token|secret|password)
      description: Instruction content directing an agent to walk integer resource IDs across tenant boundaries and collect the credentials it finds — weaponised CVE-2026-54052 technique in a skill or prompt
response:
  actions:
    - block_tool
    - alert
    - escalate
  auto_response_threshold: critical
  message_template: |
    [ATR-2026-02406] CRITICAL: sequential integer ID enumeration against an MCP tool detected (CVE-2026-54052 class, CVSS 9.6). An agent or client is walking an auto-increment record identifier — versionId / backup_id / snapshot_id — rather than requesting a specific authorised object, or the deployment pins a vulnerable n8n-mcp release with ENABLE_MULTI_TENANT=true. Where the server does not scope the query by tenant this reads other tenants' workflow snapshots, including embedded API keys and bearer tokens, and can delete their backups. Block the tool invocation, upgrade n8n-mcp to v2.56.1 or later, or set DISABLED_TOOLS=n8n_workflow_versions until the resource is ownership-checked. Rotate any credential stored in a workflow version that was readable during the exposure window.
confidence: 78
