title: Dot-Dot Path Segment Inside an Identifier-Typed Tool Argument (REST-Wrapper Path Traversal)
id: ATR-2026-02867
rule_version: 1
status: experimental
description: |
  Detects a tool-call argument whose KEY says it is an opaque identifier (product_number, licensee_number, customer_id, order_no, user_uuid, productNumber, productId, ...) but whose VALUE carries a dot-dot path segment: a '..' (or %2e%2e, .%2e, %2e.) that starts the value or follows a separator, and is itself followed by a separator ('/', '\', %2f, %5c) or by the end of the value.
  This is the shape of CVE-2026-57496 / GHSA-hxpf-9xvq-wph8 in the NetLicensing MCP Server (< 0.1.8): netlicensing_get_product interpolated the caller-controlled product_number into the REST path /product/{product_number}. A single product_number of "../token" is normalised by httpx from /product/../token to /token, the response is serialised through the ordinary wrapper instead of the token-redacting one, and the raw API token is returned to the agent. The fix (commit b8fd0ea) added a path-segment validator that rejects '..', '..%2f', '%2e%2e/', backslashes and encoded separators.
  The rule is deliberately not vendor-scoped. Any MCP server that wraps a REST API by formatting identifier arguments into a URL path has the same bug class, and an identifier never legitimately contains a dot-dot path segment. It keys on the identifier-typed argument name rather than on the tool name or on the '/token' target, so it also fires on licensee_number, a camelCase productNumber, a bare '..' (which walks to the API root) or an encoded separator.
  Why a new rule rather than relying on existing ones (measured 2026-10-22 on origin/main 69f7f2809 with tool_call and mcp_exchange events whose tool_args is the JSON-encoded argument object): the GHSA PoC {"product_number":"../token"}, "%2e%2e/token", "..\\token" and {"licensee_number":"../token"} matched no rule. ATR-2026-01948 targets this exact CVE but its key regexes expect product_number to be followed directly by ':' or '=', so the closing JSON quote of a real tool_args key defeats it; ATR-2026-02251 / 02353 have the same key-quote gap and list only *_id fields. ATR-2026-00569 catches only the '..%2f' encoding and ATR-2026-00066 / 01616 need two or more '../' levels, while one level is enough against a REST path.
  Related rule: ATR-2026-01948 (context-exfiltration) is the vendor-specific rule for this same CVE. This rule is the generalised identifier-argument form; keep the two cross-referenced when either is merged, narrowed or retired.
  Scope and limits. Only JSON double-quoted keys are read ("key": "value"), so a JSON-escaped snippet quoted inside another argument (an agent writing an advisory) does not match. Path-typed keys (path, file, dir, url, key, object_key) are intentionally out of scope - they are covered by the file-path traversal rules - so a traversal smuggled through a key with a non-identifier name (sku, name, product) is not detected here. *_code keys are also out of scope: source_code / python_code / shell_code usually hold free-form program text in which '/../' is ordinary, so product_code / promo_code identifiers are an accepted gap. Plural keys (product_numbers) and array values are not read, and a Tomcat-style path parameter ('..;/token') is not in the separator set. Keys that only END in "id" are matched case-insensitively, so a non-identifier key such as "valid" or "android" holding a dot-dot segment would also match, and identifier keys that legitimately carry a relative path (model_id, doc_id, folder_id) will match as well. CWE-22, CWE-23.
author: ATR Community (CVE sync)
date: 2026/10/22
schema_version: '0.1'
detection_tier: pattern
maturity: test
severity: high
references:
  cve:
    - CVE-2026-57496
  ghsa:
    - GHSA-hxpf-9xvq-wph8
  cwe:
    - CWE-22
    - CWE-23
  owasp_llm:
    - LLM06:2025
  owasp_agentic:
    - ASI03:2026
    - ASI02:2026
  mitre_atlas:
    - AML.T0053 - AI Agent Tool Invocation
    - AML.T0055 - Unsecured Credentials
  mitre_attack:
    - T1552 - Unsecured Credentials
  external:
    - https://github.com/Labs64/NetLicensing-MCP/security/advisories/GHSA-hxpf-9xvq-wph8
    - https://github.com/Labs64/NetLicensing-MCP/commit/b8fd0ea76d533202573eb24add9fb2fbd9331496
    - https://nvd.nist.gov/vuln/detail/CVE-2026-57496
metadata_provenance:
  cve: human-reviewed
  cwe: human-reviewed
  owasp_llm: human-reviewed
  owasp_agentic: human-reviewed
  mitre_atlas: human-reviewed
  mitre_attack: human-reviewed
compliance:
  eu_ai_act:
    - article: '15'
      context: Article 15 (accuracy, robustness and cybersecurity) requires resilience against attempts to exploit system vulnerabilities; this rule provides detection evidence supporting that requirement by flagging an identifier argument that steers an MCP server's REST request onto an unintended endpoint such as /token.
      strength: primary
    - article: '14'
      context: Article 14 (human oversight) needs operators to be able to see and interrupt anomalous agent actions; an alert on a traversal-bearing identifier argument provides detection evidence supporting oversight of tool calls that would otherwise silently return credentials to the model.
      strength: secondary
  nist_ai_rmf:
    - subcategory: MS.2.7
      context: MEASURE 2.7 requires AI system security and resilience to be evaluated; inspecting identifier-typed tool arguments for dot-dot path segments is a per-invocation measurement of the agent-to-tool boundary rather than an assumption that each MCP server validates its own path segments.
      strength: primary
    - subcategory: MG.2.3
      context: MANAGE 2.3 requires procedures to respond to and recover from identified AI risks; this rule is the runtime trigger for responding to a privilege-escalating path traversal through an agent tool argument.
      strength: secondary
  iso_42001:
    - clause: '8.1'
      context: Clause 8.1 operational planning and control covers externally provided processes such as third-party MCP servers; this rule is an operational control applied to each tool invocation independent of the server's own input validation.
      strength: primary
    - clause: '6.2'
      context: Clause 6.2 AI objectives and planning to achieve them include keeping credentials out of model context; detecting the traversal that reroutes a lookup onto a token endpoint supports that objective.
      strength: secondary
tags:
  category: privilege-escalation
  subcategory: identifier-argument-path-traversal
  scan_target: tool_args
  confidence: medium
  source: cve-disclosure
  vendor_sources: netlicensing-mcp-cve-2026-57496
  suppress_in_code_blocks: true
agent_source:
  type: tool_call
  framework:
    - mcp
    - any
  provider:
    - any
detection:
  condition: any
  method: pattern
  false_positives:
    - 'A tool whose API genuinely uses ''..'' as an identifier, for example a filesystem-browser tool that addresses the parent entry as {"entry_id": ".."}. Such an argument is itself a traversal and will match.'
    - Security test fixtures and CVE reproductions that pass the traversal payload through a real tool call match by design.
    - Keys that end in 'id' are matched case-insensitively (the engine compiles this condition format with flag 'i'), so a non-identifier key such as 'valid' or 'android' holding a dot-dot segment would also match.
    - 'Identifier-named keys that legitimately hold a relative filesystem path will match: a Hugging Face from_pretrained-style local checkpoint {"model_id": "../checkpoints/llama-ft"}, a RAG or document tool that uses the file path as the document id {"doc_id": "docs/../README.md"}, or a folder-navigation tool addressing the parent folder {"folder_id": ".."}. These are indistinguishable from the traversal by value alone; suppress per tool when the target server resolves such ids against a sandboxed root.'
  conditions:
    - field: tool_args
      operator: regex
      value: '"(?:[a-z0-9_-]{0,40}[_-](?:id|number|num|no|nr|uuid|guid|slug)|[a-z0-9]{1,40}(?:number|uuid|guid|id)|id|number|uuid|guid|slug)"\s{0,3}:\s{0,3}"(?:[^"\n]{0,120}?(?:/|\\|%2f|%5c))?(?:\.\.|%2e%2e|\.%2e|%2e\.|%252e%252e)(?:/|\\|%2f|%5c|%252f|%255c|")'
      description: An identifier-typed JSON argument (snake_case *_id/*_number/*_no/*_uuid/*_slug, camelCase *Number/*Id/*Uuid, or a bare id/number key; *_code keys excluded because they usually carry program text) whose value contains a dot-dot path segment - at the start of the value or after a separator, followed by a separator or the end of the value - literal or percent-encoded
response:
  actions:
    - alert
    - snapshot
  actions_rationale: 'response-action eligibility (docs/RESPONSE-ACTION-ELIGIBILITY.md): new CVE-derived candidate without a benign-corpus FP measurement beyond the CI gate; ceiling = observe.'
  notify:
    - security_team
  message_template: |
    [ATR-2026-02867] HIGH: an identifier-typed tool argument contains a dot-dot path segment. Opaque IDs never contain '..'; when an MCP server formats the ID into a REST path, the segment is normalised away and the request lands on a different endpoint (CVE-2026-57496: product_number "../token" reached /token and leaked the API token). Check whether the target server validates path segments before building URLs.
confidence: 72
