n8n has a Webhook Node IP Whitelist Bypass via Partial String Matching
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.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
n8nnpm | >= 1.36.0, < 2.2.0 | 2.2.0 |
Affected products
1Patches
111f8597d4ad6fix(Webhook Node): Use CIDR matching for IP whitelist check (#23399)
2 files changed · +26 −7
packages/nodes-base/nodes/Webhook/test/utils.test.ts+4 −0 modified@@ -257,6 +257,10 @@ describe('Webhook Utils', () => { ).toBe(false); }); + it('CAT-1846: should use CIDR matching to determine if ip is in the whitelist', () => { + expect(isIpWhitelisted('192.168.1.3', [], '192.168.1.30')).toBe(false); + }); + it('should handle comma-separated whitelist string', () => { expect(isIpWhitelisted('192.168.1.1, 192.168.1.2', ['192.168.1.3'], '192.168.1.2')).toBe( true,
packages/nodes-base/nodes/Webhook/utils.ts+22 −7 modified@@ -10,6 +10,7 @@ import type { MultiPartFormData, } from 'n8n-workflow'; import * as a from 'node:assert'; +import { BlockList } from 'node:net'; import { WebhookAuthorizationError } from './error'; import { formatPrivateKey } from '../../utils/utilities'; @@ -137,19 +138,33 @@ export const isIpWhitelisted = ( whitelist = whitelist.split(',').map((entry) => entry.trim()); } - for (const address of whitelist) { - if (ip?.includes(address)) { - return true; - } + const allowList = getAllowList(whitelist); - if (ips.some((entry) => entry.includes(address))) { - return true; - } + if (allowList.check(ip ?? '')) { + return true; + } + + if (ips.some((ipEntry) => allowList.check(ipEntry))) { + return true; } return false; }; +const getAllowList = (whitelist: string[]) => { + const allowList = new BlockList(); + + for (const entry of whitelist) { + try { + allowList.addAddress(entry); + } catch { + // Ignore invalid entries + } + } + + return allowList; +}; + export const checkResponseModeConfiguration = (context: IWebhookFunctions) => { const responseMode = context.getNodeParameter('responseMode', 'onReceived') as string; const connectedNodes = context.getChildNodes(context.getNode().name);
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-w96v-gf22-crwpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-68949ghsaADVISORY
- github.com/n8n-io/n8n/commit/11f8597d4ad69ea3b58941573997fdbc4de1fec5ghsax_refsource_MISCWEB
- github.com/n8n-io/n8n/issues/23399ghsax_refsource_MISCWEB
- github.com/n8n-io/n8n/pull/23399ghsax_refsource_MISCWEB
- github.com/n8n-io/n8n/security/advisories/GHSA-w96v-gf22-crwpghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.