netlicensing-mcp Path Traversal in product_number Bypasses Token Redaction (GHSA-hxpf-9xvq-wph8)
Detects GHSA-hxpf-9xvq-wph8 (CRITICAL): NetLicensing-MCP <= 0.1.5 interpolates the netlicensing_get_product tool's `product_number` parameter into a REST path without validation (products.py:22 -> nl_get(f"/product/{product_number}")). Supplying `../token` (or URL-encoded `%2e%2e/token`) produces `/product/../token`, which httpx normalizes to the `/token` endpoint. The response is wrapped as a Product instead of a token, skipping redact_token_read(), so the raw APIKEY ("number" field), "shopURL", and "console_url" plaintext secret are returned. This rule keys on the product_number = ../token traversal payload and its encoded variants reaching the netlicensing product tool/path.
Response Actions
References
Detection Conditions
Combinator: any- 01netlicensing_get_product product_number parameter set to ../token or %2e%2e/token — the exact path-traversal payload that redirects /product to the /token endpointfield: contentop: regex
- 02Literal traversal path /product/../token (or encoded) that httpx normalizes to /token, leaking the raw APIKEY via skipped redact_token_readfield: contentop: regex
- 03The netlicensing get_product tool invoked with a ../token traversal argumentfield: contentop: regex
- 04explicit GHSA framing combined with the traversal/redaction-bypass keywordsfield: contentop: regex
Attack Examples (Rule Triggers)
netlicensing_get_product(product_number="../token")
{"tool": "netlicensing_get_product", "arguments": {"product_number": "%2e%2e/token"}}GET /core/v2/rest/product/../token (normalizes to /core/v2/rest/token and returns the raw number/APIKEY field)
GHSA-hxpf-9xvq-wph8: set product_number to ../token to bypass redact_token_read and leak the console_url plaintext secret
Real-world attack payloads, sanitized and versioned alongside the rule as regression tests — so a future revision can't silently stop catching them.
Benign Examples (Rule Doesn't Trigger)
- Legitimate product lookup with a real alphanumeric product number, no traversal
netlicensing_get_product(product_number="PRD-2026-0042")
- Doc describing the two endpoints separately without a ../token traversal payload
The netlicensing-mcp server exposes /product/{number} and a separate /token endpoint for license management. - Normal get_product tool call with a benign product number string
{"tool": "netlicensing_get_product", "arguments": {"product_number": "STARTER-PLAN"}}
Known False Positive Contexts
- ▸A legitimate netlicensing_get_product call with a real alphanumeric product_number (e.g. product_number=PRD-001) that contains no ../ traversal.
- ▸Documentation describing the /product/{number} and /token REST endpoints separately without a traversal payload joining them.
- ▸Generic mention of the netlicensing-mcp server or its tools without the ../token product_number payload.
Full YAML Definition
Edit on GitHub →title: "netlicensing-mcp Path Traversal in product_number Bypasses Token Redaction (GHSA-hxpf-9xvq-wph8)"
id: ATR-2026-01948
rule_version: 1
status: draft
description: >
Detects GHSA-hxpf-9xvq-wph8 (CRITICAL): NetLicensing-MCP <= 0.1.5 interpolates the
netlicensing_get_product tool's `product_number` parameter into a REST path without
validation (products.py:22 -> nl_get(f"/product/{product_number}")). Supplying
`../token` (or URL-encoded `%2e%2e/token`) produces `/product/../token`, which httpx
normalizes to the `/token` endpoint. The response is wrapped as a Product instead of a
token, skipping redact_token_read(), so the raw APIKEY ("number" field), "shopURL", and
"console_url" plaintext secret are returned. This rule keys on the product_number =
../token traversal payload and its encoded variants reaching the netlicensing product
tool/path.
author: "ATR Community"
date: "2026/06/29"
schema_version: "0.1"
detection_tier: pattern
maturity: test
severity: critical
references:
owasp_llm:
- "LLM06:2025 - Excessive Agency"
owasp_agentic:
- "ASI06:2026 - Tool Misuse"
mitre_atlas:
- "AML.T0049 - Exploit Public-Facing Application"
mitre_attack:
- "T1190 - Exploit Public-Facing Application"
cve:
- "GHSA-hxpf-9xvq-wph8"
metadata_provenance:
mitre_atlas: human-reviewed
owasp_llm: human-reviewed
owasp_agentic: human-reviewed
compliance:
eu_ai_act:
- article: "15"
context: "Article 15 (accuracy, robustness, cybersecurity) — runtime detection of this technique is a cybersecurity control for high-risk AI systems. Technique: netlicensing-mcp Path Traversal in product_number Bypasses Token Redaction (GHSA-hxpf-9xvq-wph8)."
strength: primary
- article: "9"
context: "Article 9 (risk management system) requires identified risks to be addressed by appropriate measures; this rule is a runtime risk-treatment control. Technique: netlicensing-mcp Path Traversal in product_number Bypasses Token Redaction (GHSA-hxpf-9xvq-wph8)."
strength: secondary
nist_ai_rmf:
- subcategory: "MP.5.1"
context: "NIST AI RMF MAP 5.1 — likelihood and impact of the identified attack are characterised; this rule detects the adversarial input at runtime. Technique: netlicensing-mcp Path Traversal in product_number Bypasses Token Redaction (GHSA-hxpf-9xvq-wph8)."
strength: primary
- subcategory: "MG.3.2"
context: "NIST AI RMF MANAGE 3.2 — runtime monitoring/maintenance control that surfaces this attack class. Technique: netlicensing-mcp Path Traversal in product_number Bypasses Token Redaction (GHSA-hxpf-9xvq-wph8)."
strength: secondary
iso_42001:
- clause: "8.1"
context: "ISO/IEC 42001 Clause 8.1 (operational planning and control) — detection of this payload is an operational control. Technique: netlicensing-mcp Path Traversal in product_number Bypasses Token Redaction (GHSA-hxpf-9xvq-wph8)."
strength: primary
- clause: "8.3"
context: "ISO/IEC 42001 Clause 8.3 (AI risk treatment) — this rule implements runtime detection as a treatment control. Technique: netlicensing-mcp Path Traversal in product_number Bypasses Token Redaction (GHSA-hxpf-9xvq-wph8)."
strength: secondary
tags:
category: context-exfiltration
subcategory: rest-path-traversal-token-leak
scan_target: both
confidence: high
source: cve-disclosure
vendor_sources: netlicensing-mcp-ghsa-hxpf-9xvq-wph8
agent_source:
type: llm_io
framework:
- any
provider:
- any
detection:
condition: any
false_positives:
- "A legitimate netlicensing_get_product call with a real alphanumeric product_number (e.g. product_number=PRD-001) that contains no ../ traversal."
- "Documentation describing the /product/{number} and /token REST endpoints separately without a traversal payload joining them."
- "Generic mention of the netlicensing-mcp server or its tools without the ../token product_number payload."
conditions:
- field: content
operator: regex
value: '(?i)product_number\s*[=:]\s*["\x27]?\s*(?:\.\.|%2e%2e)\s*[/\\]\s*token'
description: >
netlicensing_get_product product_number parameter set to ../token or %2e%2e/token —
the exact path-traversal payload that redirects /product to the /token endpoint
- field: content
operator: regex
value: '(?i)/product/\s*(?:\.\.|%2e%2e)\s*[/\\]\s*token'
description: >
Literal traversal path /product/../token (or encoded) that httpx normalizes to
/token, leaking the raw APIKEY via skipped redact_token_read
- field: content
operator: regex
value: '(?i)(?:netlicensing[_-]?get[_-]?product|get_product)[\s\S]{0,120}(?:\.\.|%2e%2e)[/\\]token'
description: >
The netlicensing get_product tool invoked with a ../token traversal argument
- field: content
operator: regex
value: '(?i)GHSA-hxpf-9xvq-wph8[\s\S]{0,200}(?:path\s*traversal|product_number|\.\./token|redact|token\s*redaction)'
description: "explicit GHSA framing combined with the traversal/redaction-bypass keywords"
response:
actions:
- alert
- block_input
message_template: >
[ATR-2026-01948] CRITICAL: netlicensing-mcp product_number path traversal (../token)
bypasses token redaction and leaks the raw NetLicensing APIKEY. Block and upgrade to
netlicensing-mcp >= 0.1.8.
confidence: 80
wild_fp_rate: 0
test_cases:
true_positives:
- input: 'netlicensing_get_product(product_number="../token")'
expected: triggered
description: "Exact GHSA-hxpf-9xvq-wph8 PoC: product_number=../token traverses /product to /token leaking the APIKEY"
- input: '{"tool": "netlicensing_get_product", "arguments": {"product_number": "%2e%2e/token"}}'
expected: triggered
description: "URL-encoded %2e%2e/token traversal payload in the tool arguments"
- input: "GET /core/v2/rest/product/../token (normalizes to /core/v2/rest/token and returns the raw number/APIKEY field)"
expected: triggered
description: "Literal /product/../token path that httpx normalizes to the token endpoint"
- input: "GHSA-hxpf-9xvq-wph8: set product_number to ../token to bypass redact_token_read and leak the console_url plaintext secret"
expected: triggered
description: "Explicit advisory reference with the traversal + redaction-bypass exploit description"
true_negatives:
- input: 'netlicensing_get_product(product_number="PRD-2026-0042")'
expected: not_triggered
description: "Legitimate product lookup with a real alphanumeric product number, no traversal"
- input: "The netlicensing-mcp server exposes /product/{number} and a separate /token endpoint for license management."
expected: not_triggered
description: "Doc describing the two endpoints separately without a ../token traversal payload"
- input: '{"tool": "netlicensing_get_product", "arguments": {"product_number": "STARTER-PLAN"}}'
expected: not_triggered
description: "Normal get_product tool call with a benign product number string"