[{"data":1,"prerenderedAt":1175},["ShallowReactive",2],{"content-query-LFf5uyZ71H":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"head":11,"author":12,"tags":13,"categories":19,"date":20,"faq":21,"excerpt":43,"body":65,"_type":1167,"_id":1168,"_source":1169,"_file":1170,"_stem":1171,"_extension":1172,"sitemap":1173,"readingTime":1174},"/blog/n8n-security","blog",false,"","n8n Security: CVE-2025-68613 and Keeping the Editor Private","n8n security after CVE-2025-68613: what the n8n vulnerabilities allow, why the editor must stay private, and how to receive n8n webhooks without exposing it.","post",{"title":8},"Karolis Rusenas",[14,15,16,17,18],"n8n","security","webhooks","automation","self-hosted",[15],"2026-10-28 12:00:00",[22,25,28,31,34,37,40],{"q":23,"a":24},"Is n8n secure to self-host?","It can be, if you patch promptly and keep the editor and login page off the public internet. n8n has had several serious advisories in its expression engine and form handling (CVE-2025-68613, its follow-up CVE-2026-25049, and CVE-2026-21858), so run a current release, limit who can create or edit workflows, and expose only what an external sender needs.",{"q":26,"a":27},"What is CVE-2025-68613?","CVE-2025-68613 is an expression injection flaw in n8n's workflow expression evaluator. A user who can create or edit workflows could run code with the privileges of the n8n process, which can lead to takeover of the instance and the credentials stored in it. It is fixed in n8n 1.120.4, 1.121.1 and 1.122.0, and CISA lists it as exploited.",{"q":29,"a":30},"Does CVE-2025-68613 need a login?","Yes. The attacker needs an authenticated account that can create or modify workflows. That is why keeping the editor and login page off the internet matters: it removes the public path to the account prompt, although anyone who already holds a valid account can still reach the bug on an unpatched instance.",{"q":32,"a":33},"What is the difference between the n8n webhook test URL and production URL?","n8n's Webhook node has two URLs. The test URL uses the /webhook-test/ path and is registered only while you listen for a test event in the editor. The production URL uses the /webhook/ path and is registered when the workflow is active. Both paths are configurable with N8N_ENDPOINT_WEBHOOK_TEST and N8N_ENDPOINT_WEBHOOK.",{"q":35,"a":36},"Do I need to expose n8n to the internet to receive webhooks?","Not if you use an outbound relay. With the Webhook Relay Trigger community node, n8n opens an outbound WebSocket and the provider calls a public relay URL, so n8n listens for nothing inbound. Alternatively, a relay agent can forward deliveries to n8n's /webhook/ path on a private address.",{"q":38,"a":39},"What does WEBHOOK_URL do in n8n?","It tells n8n its public base URL, so the editor displays the right webhook URLs and registers the correct ones with external services when n8n runs behind a reverse proxy. The current n8n docs name the variable N8N_WEBHOOK_URL and describe WEBHOOK_URL as deprecated, so check which one your version expects.",{"q":41,"a":42},"Does a webhook relay fix CVE-2025-68613?","No. It does not patch anything. It removes the internet-reachable editor and login page, which an attacker needs in order to reach the bug. Upgrade n8n to a fixed release regardless.",{"type":44,"children":45},"root",[46,60],{"type":47,"tag":48,"props":49,"children":50},"element","p",{},[51,58],{"type":47,"tag":52,"props":53,"children":54},"strong",{},[55],{"type":56,"value":57},"text","n8n security comes down to two habits: run a patched release, and keep the editor and its REST API off the public internet.",{"type":56,"value":59}," Most self-hosted n8n instances are public for one reason, which is that Webhook nodes need a URL the outside world can call. You can serve that URL without exposing the editor by receiving webhooks through an outbound relay, so the login page and workflow editor are not reachable from the internet.",{"type":47,"tag":48,"props":61,"children":62},{},[63],{"type":56,"value":64},"This post covers the n8n vulnerability record that matters (centered on CVE-2025-68613), what each flaw needs from an attacker, and how to set up n8n so only webhook deliveries arrive.",{"type":44,"children":66,"toc":1153},[67,75,79,86,102,243,248,292,306,312,317,322,328,342,484,506,551,557,562,569,582,705,717,723,735,812,853,881,886,892,986,1005,1011,1016,1076,1082,1088,1127,1147],{"type":47,"tag":48,"props":68,"children":69},{},[70,74],{"type":47,"tag":52,"props":71,"children":72},{},[73],{"type":56,"value":57},{"type":56,"value":59},{"type":47,"tag":48,"props":76,"children":77},{},[78],{"type":56,"value":64},{"type":47,"tag":80,"props":81,"children":83},"h2",{"id":82},"the-n8n-vulnerabilities-worth-knowing",[84],{"type":56,"value":85},"The n8n vulnerabilities worth knowing",{"type":47,"tag":48,"props":87,"children":88},{},[89,91,100],{"type":56,"value":90},"Three n8n advisories explain most of the current n8n security discussion. The first is in our ",{"type":47,"tag":92,"props":93,"children":97},"a",{"href":94,"rel":95},"https://helix.ml/threat-watch",[96],"nofollow",[98],{"type":56,"value":99},"Threat Watch",{"type":56,"value":101}," feed, which records verified facts; the other two we checked directly against n8n's own GitHub advisories.",{"type":47,"tag":103,"props":104,"children":105},"table",{},[106,140],{"type":47,"tag":107,"props":108,"children":109},"thead",{},[110],{"type":47,"tag":111,"props":112,"children":113},"tr",{},[114,120,125,130,135],{"type":47,"tag":115,"props":116,"children":117},"th",{},[118],{"type":56,"value":119},"CVE",{"type":47,"tag":115,"props":121,"children":122},{},[123],{"type":56,"value":124},"What an attacker gets",{"type":47,"tag":115,"props":126,"children":127},{},[128],{"type":56,"value":129},"Auth needed",{"type":47,"tag":115,"props":131,"children":132},{},[133],{"type":56,"value":134},"Exploited in the wild",{"type":47,"tag":115,"props":136,"children":137},{},[138],{"type":56,"value":139},"Fixed in",{"type":47,"tag":141,"props":142,"children":143},"tbody",{},[144,178,211],{"type":47,"tag":111,"props":145,"children":146},{},[147,158,163,168,173],{"type":47,"tag":148,"props":149,"children":150},"td",{},[151],{"type":47,"tag":92,"props":152,"children":155},{"href":153,"rel":154},"https://helix.ml/threat-watch/i/n8n-n8n-cve-2025-68613",[96],[156],{"type":56,"value":157},"CVE-2025-68613, expression injection to code execution",{"type":47,"tag":148,"props":159,"children":160},{},[161],{"type":56,"value":162},"Code execution with the n8n process's privileges: the instance, its stored credentials and workflows",{"type":47,"tag":148,"props":164,"children":165},{},[166],{"type":56,"value":167},"Yes: an account that can create or edit workflows",{"type":47,"tag":148,"props":169,"children":170},{},[171],{"type":56,"value":172},"Yes: CISA added it to the Known Exploited Vulnerabilities catalog on 2026-03-11",{"type":47,"tag":148,"props":174,"children":175},{},[176],{"type":56,"value":177},"1.120.4, 1.121.1, 1.122.0",{"type":47,"tag":111,"props":179,"children":180},{},[181,191,196,201,206],{"type":47,"tag":148,"props":182,"children":183},{},[184],{"type":47,"tag":92,"props":185,"children":188},{"href":186,"rel":187},"https://github.com/n8n-io/n8n/security/advisories/GHSA-6cqr-8cfr-67f8",[96],[189],{"type":56,"value":190},"CVE-2026-25049, expression escape",{"type":47,"tag":148,"props":192,"children":193},{},[194],{"type":56,"value":195},"Command execution on the host, via further expression-evaluation bypasses after CVE-2025-68613",{"type":47,"tag":148,"props":197,"children":198},{},[199],{"type":56,"value":200},"Yes: permission to create or modify workflows",{"type":47,"tag":148,"props":202,"children":203},{},[204],{"type":56,"value":205},"Not stated in the advisory",{"type":47,"tag":148,"props":207,"children":208},{},[209],{"type":56,"value":210},"1.123.17, 2.5.2",{"type":47,"tag":111,"props":212,"children":213},{},[214,224,229,234,238],{"type":47,"tag":148,"props":215,"children":216},{},[217],{"type":47,"tag":92,"props":218,"children":221},{"href":219,"rel":220},"https://github.com/n8n-io/n8n/security/advisories/GHSA-v4pr-fm98-w9pg",[96],[222],{"type":56,"value":223},"CVE-2026-21858, file access via form workflows",{"type":47,"tag":148,"props":225,"children":226},{},[227],{"type":56,"value":228},"Access to files on the underlying server through certain form-based workflows (CVSS 10.0 in the advisory)",{"type":47,"tag":148,"props":230,"children":231},{},[232],{"type":56,"value":233},"No",{"type":47,"tag":148,"props":235,"children":236},{},[237],{"type":56,"value":205},{"type":47,"tag":148,"props":239,"children":240},{},[241],{"type":56,"value":242},"1.121.0",{"type":47,"tag":48,"props":244,"children":245},{},[246],{"type":56,"value":247},"Details worth keeping straight:",{"type":47,"tag":249,"props":250,"children":251},"ul",{},[252,272,282],{"type":47,"tag":253,"props":254,"children":255},"li",{},[256,261,263,270],{"type":47,"tag":52,"props":257,"children":258},{},[259],{"type":56,"value":260},"CVE-2025-68613",{"type":56,"value":262}," affects builds from 0.211.0 up to the fixed releases. Per the ",{"type":47,"tag":92,"props":264,"children":267},{"href":265,"rel":266},"https://github.com/n8n-io/n8n/security/advisories/GHSA-v98v-ff95-f3cp",[96],[268],{"type":56,"value":269},"vendor advisory",{"type":56,"value":271},", the workarounds (restrict who can edit workflows, harden the host) only reduce risk; upgrading to 1.122.0 or later is the fix. CISA published no victim or method details.",{"type":47,"tag":253,"props":273,"children":274},{},[275,280],{"type":47,"tag":52,"props":276,"children":277},{},[278],{"type":56,"value":279},"CVE-2026-25049",{"type":56,"value":281}," is described by n8n as additional exploits in expression evaluation, found after CVE-2025-68613. Stopping at 1.122.0 is therefore not enough; move to a current release.",{"type":47,"tag":253,"props":283,"children":284},{},[285,290],{"type":47,"tag":52,"props":286,"children":287},{},[288],{"type":56,"value":289},"CVE-2026-21858",{"type":56,"value":291}," affects versions from 1.65.0 before 1.121.0. n8n says there is no official workaround, and suggests restricting or disabling publicly accessible webhook and form endpoints until you upgrade. We did not find a Threat Watch record for it, so the link above goes to the vendor advisory.",{"type":47,"tag":48,"props":293,"children":294},{},[295,297,304],{"type":56,"value":296},"One more n8n item is unrelated to self-hosting: in October 2026 the hosted ",{"type":47,"tag":92,"props":298,"children":301},{"href":299,"rel":300},"https://helix.ml/threat-watch/i/n8n-creators-template-library-unpublished-templates-readable-without-login",[96],[302],{"type":56,"value":303},"creators portal served templates still in review without a login",{"type":56,"value":305},". A workflow template can embed API keys and webhook URLs, so if you submitted templates, rotate anything they contained.",{"type":47,"tag":80,"props":307,"children":309},{"id":308},"why-exposure-is-the-real-risk-multiplier",[310],{"type":56,"value":311},"Why exposure is the real risk multiplier",{"type":47,"tag":48,"props":313,"children":314},{},[315],{"type":56,"value":316},"Two of the three flaws above need a valid account. That sounds reassuring until you look at what an exposed instance offers an attacker: a login page on the internet, reachable by every scanner, with a credential store behind it. Account takeover, a leaked password, a low-privilege user added for one project, or a phished editor all become a path to the host once an unpatched expression bug exists.",{"type":47,"tag":48,"props":318,"children":319},{},[320],{"type":56,"value":321},"If the editor is only reachable from a private network or VPN, the same bug still exists, but the attacker must first get onto that network. Reducing who can even attempt a login is the cheapest layer of defense you have, and it does not depend on you winning every patch race.",{"type":47,"tag":80,"props":323,"children":325},{"id":324},"exactly-what-to-expose-and-what-not-to",[326],{"type":56,"value":327},"Exactly what to expose, and what not to",{"type":47,"tag":48,"props":329,"children":330},{},[331,333,340],{"type":56,"value":332},"n8n serves several things from one process. By default, per the ",{"type":47,"tag":92,"props":334,"children":337},{"href":335,"rel":336},"https://docs.n8n.io/hosting/configuration/environment-variables/endpoints/",[96],[338],{"type":56,"value":339},"n8n endpoint variables",{"type":56,"value":341},":",{"type":47,"tag":103,"props":343,"children":344},{},[345,366],{"type":47,"tag":107,"props":346,"children":347},{},[348],{"type":47,"tag":111,"props":349,"children":350},{},[351,356,361],{"type":47,"tag":115,"props":352,"children":353},{},[354],{"type":56,"value":355},"Path (default)",{"type":47,"tag":115,"props":357,"children":358},{},[359],{"type":56,"value":360},"What it is",{"type":47,"tag":115,"props":362,"children":363},{},[364],{"type":56,"value":365},"Should the internet reach it?",{"type":47,"tag":141,"props":367,"children":368},{},[369,402,432,461],{"type":47,"tag":111,"props":370,"children":371},{},[372,392,397],{"type":47,"tag":148,"props":373,"children":374},{},[375,382,384,390],{"type":47,"tag":376,"props":377,"children":379},"code",{"className":378},[],[380],{"type":56,"value":381},"/webhook/",{"type":56,"value":383}," (",{"type":47,"tag":376,"props":385,"children":387},{"className":386},[],[388],{"type":56,"value":389},"N8N_ENDPOINT_WEBHOOK",{"type":56,"value":391},")",{"type":47,"tag":148,"props":393,"children":394},{},[395],{"type":56,"value":396},"Production webhook URLs, live while a workflow is active",{"type":47,"tag":148,"props":398,"children":399},{},[400],{"type":56,"value":401},"Only if a sender needs it, ideally via a relay",{"type":47,"tag":111,"props":403,"children":404},{},[405,422,427],{"type":47,"tag":148,"props":406,"children":407},{},[408,414,415,421],{"type":47,"tag":376,"props":409,"children":411},{"className":410},[],[412],{"type":56,"value":413},"/webhook-test/",{"type":56,"value":383},{"type":47,"tag":376,"props":416,"children":418},{"className":417},[],[419],{"type":56,"value":420},"N8N_ENDPOINT_WEBHOOK_TEST",{"type":56,"value":391},{"type":47,"tag":148,"props":423,"children":424},{},[425],{"type":56,"value":426},"Test webhook URLs, registered while you listen for a test event in the editor",{"type":47,"tag":148,"props":428,"children":429},{},[430],{"type":56,"value":431},"No. You call this yourself from a private network",{"type":47,"tag":111,"props":433,"children":434},{},[435,452,457],{"type":47,"tag":148,"props":436,"children":437},{},[438,444,445,451],{"type":47,"tag":376,"props":439,"children":441},{"className":440},[],[442],{"type":56,"value":443},"/rest/",{"type":56,"value":383},{"type":47,"tag":376,"props":446,"children":448},{"className":447},[],[449],{"type":56,"value":450},"N8N_ENDPOINT_REST",{"type":56,"value":391},{"type":47,"tag":148,"props":453,"children":454},{},[455],{"type":56,"value":456},"The internal REST API the editor and login use",{"type":47,"tag":148,"props":458,"children":459},{},[460],{"type":56,"value":233},{"type":47,"tag":111,"props":462,"children":463},{},[464,475,480],{"type":47,"tag":148,"props":465,"children":466},{},[467,473],{"type":47,"tag":376,"props":468,"children":470},{"className":469},[],[471],{"type":56,"value":472},"/",{"type":56,"value":474}," (editor UI)",{"type":47,"tag":148,"props":476,"children":477},{},[478],{"type":56,"value":479},"The workflow editor and sign-in page",{"type":47,"tag":148,"props":481,"children":482},{},[483],{"type":56,"value":233},{"type":47,"tag":48,"props":485,"children":486},{},[487,489,496,498,504],{"type":56,"value":488},"The ",{"type":47,"tag":92,"props":490,"children":493},{"href":491,"rel":492},"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/",[96],[494],{"type":56,"value":495},"Webhook node documentation",{"type":56,"value":497}," confirms the two URL types: a test URL, registered when you select Listen for Test Event, and a production URL, registered when the workflow is published. Production calls look like ",{"type":47,"tag":376,"props":499,"children":501},{"className":500},[],[502],{"type":56,"value":503},"https://\u003Cyour-n8n-url>/webhook/my-path",{"type":56,"value":505},".",{"type":47,"tag":48,"props":507,"children":508},{},[509,511,518,520,526,528,534,536,542,544,549],{"type":56,"value":510},"A conventional setup publishes the whole origin through a reverse proxy, then sets the public base URL so n8n shows the right webhook addresses. The ",{"type":47,"tag":92,"props":512,"children":515},{"href":513,"rel":514},"https://docs.n8n.io/hosting/configuration/configuration-examples/webhook-url/",[96],[516],{"type":56,"value":517},"reverse proxy guide",{"type":56,"value":519}," says to set ",{"type":47,"tag":376,"props":521,"children":523},{"className":522},[],[524],{"type":56,"value":525},"N8N_WEBHOOK_URL",{"type":56,"value":527}," (it replaces the older ",{"type":47,"tag":376,"props":529,"children":531},{"className":530},[],[532],{"type":56,"value":533},"WEBHOOK_URL",{"type":56,"value":535},", which the docs describe as deprecated) and ",{"type":47,"tag":376,"props":537,"children":539},{"className":538},[],[540],{"type":56,"value":541},"N8N_PROXY_HOPS=1",{"type":56,"value":543},". That is correct for a proxied instance, but note what it implies: the editor and ",{"type":47,"tag":376,"props":545,"children":547},{"className":546},[],[548],{"type":56,"value":443},{"type":56,"value":550}," are now on the internet too, unless you filter paths yourself.",{"type":47,"tag":80,"props":552,"children":554},{"id":553},"receive-n8n-webhooks-without-exposing-the-editor",[555],{"type":56,"value":556},"Receive n8n webhooks without exposing the editor",{"type":47,"tag":48,"props":558,"children":559},{},[560],{"type":56,"value":561},"Webhook Relay gives senders a stable public URL and delivers each request to n8n over a connection that n8n opens outward. Pick one of two paths.",{"type":47,"tag":563,"props":564,"children":566},"h3",{"id":565},"option-a-the-webhook-relay-trigger-node-no-inbound-listener",[567],{"type":56,"value":568},"Option A: the Webhook Relay Trigger node (no inbound listener)",{"type":47,"tag":48,"props":570,"children":571},{},[572,574,580],{"type":56,"value":573},"This is the primary path, documented in the ",{"type":47,"tag":92,"props":575,"children":577},{"href":576},"/docs/tutorials/n8n/webhook-trigger/",[578],{"type":56,"value":579},"n8n Webhook Trigger tutorial",{"type":56,"value":581},". The node opens an outbound WebSocket, so nothing in n8n has to be reachable from outside.",{"type":47,"tag":583,"props":584,"children":585},"ol",{},[586,614,635,668,687],{"type":47,"tag":253,"props":587,"children":588},{},[589,591,596,598,604,605,612],{"type":56,"value":590},"In n8n, go to ",{"type":47,"tag":52,"props":592,"children":593},{},[594],{"type":56,"value":595},"Settings > Community Nodes > Install",{"type":56,"value":597}," and enter ",{"type":47,"tag":376,"props":599,"children":601},{"className":600},[],[602],{"type":56,"value":603},"n8n-nodes-webhookrelay",{"type":56,"value":383},{"type":47,"tag":92,"props":606,"children":609},{"href":607,"rel":608},"https://www.npmjs.com/package/n8n-nodes-webhookrelay",[96],[610],{"type":56,"value":611},"npm package",{"type":56,"value":613},").",{"type":47,"tag":253,"props":615,"children":616},{},[617,619,626,628,633],{"type":56,"value":618},"Create an API key at ",{"type":47,"tag":92,"props":620,"children":623},{"href":621,"rel":622},"https://my.webhookrelay.com/tokens",[96],[624],{"type":56,"value":625},"my.webhookrelay.com/tokens",{"type":56,"value":627}," and paste it into a ",{"type":47,"tag":52,"props":629,"children":630},{},[631],{"type":56,"value":632},"Webhook Relay API",{"type":56,"value":634}," credential.",{"type":47,"tag":253,"props":636,"children":637},{},[638,640,645,647,652,654,659,661,666],{"type":56,"value":639},"Add the trigger, give it a ",{"type":47,"tag":52,"props":641,"children":642},{},[643],{"type":56,"value":644},"Bucket",{"type":56,"value":646}," name such as ",{"type":47,"tag":376,"props":648,"children":650},{"className":649},[],[651],{"type":56,"value":14},{"type":56,"value":653},", and optionally set ",{"type":47,"tag":52,"props":655,"children":656},{},[657],{"type":56,"value":658},"Endpoint Authentication",{"type":56,"value":660}," (Basic or token) and the ",{"type":47,"tag":52,"props":662,"children":663},{},[664],{"type":56,"value":665},"Response",{"type":56,"value":667}," returned to the sender.",{"type":47,"tag":253,"props":669,"children":670},{},[671,673,678,679,685],{"type":56,"value":672},"Copy the ",{"type":47,"tag":52,"props":674,"children":675},{},[676],{"type":56,"value":677},"Public URL",{"type":56,"value":383},{"type":47,"tag":376,"props":680,"children":682},{"className":681},[],[683],{"type":56,"value":684},"https://\u003Cid>.hooks.webhookrelay.com",{"type":56,"value":686},") into the provider's webhook settings.",{"type":47,"tag":253,"props":688,"children":689},{},[690,695,697,703],{"type":47,"tag":52,"props":691,"children":692},{},[693],{"type":56,"value":694},"Activate",{"type":56,"value":696}," the workflow. ",{"type":47,"tag":698,"props":699,"children":700},"em",{},[701],{"type":56,"value":702},"Test this trigger",{"type":56,"value":704}," captures a single event; activating receives events continuously.",{"type":47,"tag":48,"props":706,"children":707},{},[708,710,715],{"type":56,"value":709},"Because this node does not use n8n's own ",{"type":47,"tag":376,"props":711,"children":713},{"className":712},[],[714],{"type":56,"value":381},{"type":56,"value":716}," listener, you can bind n8n to a private address or put the editor behind a VPN or SSO without losing webhook delivery.",{"type":47,"tag":563,"props":718,"children":720},{"id":719},"option-b-the-relay-agent-forwarding-to-n8ns-own-webhook-path",[721],{"type":56,"value":722},"Option B: the relay agent forwarding to n8n's own webhook path",{"type":47,"tag":48,"props":724,"children":725},{},[726,728,734],{"type":56,"value":727},"If you prefer n8n's built-in Webhook node, run the relay agent next to n8n and forward to the production path on a private address. The commands come from the ",{"type":47,"tag":92,"props":729,"children":731},{"href":730},"/docs/webhooks/internal/localhost/",[732],{"type":56,"value":733},"localhost forwarding guide",{"type":56,"value":341},{"type":47,"tag":736,"props":737,"children":741},"pre",{"className":738,"code":739,"language":740,"meta":7,"style":7},"language-bash shiki shiki-themes github-dark","relay login -k YOUR_TOKEN_KEY -s YOUR_TOKEN_SECRET\nrelay forward --bucket n8n http://localhost:5678/webhook/my-path\n","bash",[742],{"type":47,"tag":376,"props":743,"children":744},{"__ignoreMap":7},[745,784],{"type":47,"tag":746,"props":747,"children":750},"span",{"class":748,"line":749},"line",1,[751,757,763,769,774,779],{"type":47,"tag":746,"props":752,"children":754},{"style":753},"--shiki-default:#B392F0",[755],{"type":56,"value":756},"relay",{"type":47,"tag":746,"props":758,"children":760},{"style":759},"--shiki-default:#9ECBFF",[761],{"type":56,"value":762}," login",{"type":47,"tag":746,"props":764,"children":766},{"style":765},"--shiki-default:#79B8FF",[767],{"type":56,"value":768}," -k",{"type":47,"tag":746,"props":770,"children":771},{"style":759},[772],{"type":56,"value":773}," YOUR_TOKEN_KEY",{"type":47,"tag":746,"props":775,"children":776},{"style":765},[777],{"type":56,"value":778}," -s",{"type":47,"tag":746,"props":780,"children":781},{"style":759},[782],{"type":56,"value":783}," YOUR_TOKEN_SECRET\n",{"type":47,"tag":746,"props":785,"children":787},{"class":748,"line":786},2,[788,792,797,802,807],{"type":47,"tag":746,"props":789,"children":790},{"style":753},[791],{"type":56,"value":756},{"type":47,"tag":746,"props":793,"children":794},{"style":759},[795],{"type":56,"value":796}," forward",{"type":47,"tag":746,"props":798,"children":799},{"style":765},[800],{"type":56,"value":801}," --bucket",{"type":47,"tag":746,"props":803,"children":804},{"style":759},[805],{"type":56,"value":806}," n8n",{"type":47,"tag":746,"props":808,"children":809},{"style":759},[810],{"type":56,"value":811}," http://localhost:5678/webhook/my-path\n",{"type":47,"tag":48,"props":813,"children":814},{},[815,820,822,828,830,836,838,843,845,851],{"type":47,"tag":52,"props":816,"children":817},{},[818],{"type":56,"value":819},"Lock the destination path.",{"type":56,"value":821}," By default an output appends any extra path the sender adds to the input URL (a POST to ",{"type":47,"tag":376,"props":823,"children":825},{"className":824},[],[826],{"type":56,"value":827},"\u003Cinput URL>/anything",{"type":56,"value":829}," goes to ",{"type":47,"tag":376,"props":831,"children":833},{"className":832},[],[834],{"type":56,"value":835},"\u003Cdestination>/anything",{"type":56,"value":837},"). Outputs created in the dashboard have ",{"type":47,"tag":52,"props":839,"children":840},{},[841],{"type":56,"value":842},"Destination URL path locked",{"type":56,"value":844}," switched on; outputs created with the CLI or API do not, so open the output and turn it on (API/MCP field ",{"type":47,"tag":376,"props":846,"children":848},{"className":847},[],[849],{"type":56,"value":850},"lock_path: true",{"type":56,"value":852},"). With the path locked, every delivery goes to exactly the destination URL and nothing else on n8n is reachable through the relay.",{"type":47,"tag":48,"props":854,"children":855},{},[856,858,863,865,871,873,879],{"type":56,"value":857},"The command prints a permanent public input URL, which you give to the sender. Port 5678 is n8n's internal port per the n8n docs; adjust it if you changed it. While you build the workflow, a second bucket can point at the ",{"type":47,"tag":376,"props":859,"children":861},{"className":860},[],[862],{"type":56,"value":413},{"type":56,"value":864}," path the same way. For a server, the agent also runs as the ",{"type":47,"tag":376,"props":866,"children":868},{"className":867},[],[869],{"type":56,"value":870},"webhookrelay/webhookrelayd",{"type":56,"value":872}," Docker image (see ",{"type":47,"tag":92,"props":874,"children":876},{"href":875},"/docs/installation/docker/",[877],{"type":56,"value":878},"Docker installation",{"type":56,"value":880},"); use host networking when the destination is the Docker host's localhost.",{"type":47,"tag":48,"props":882,"children":883},{},[884],{"type":56,"value":885},"With either option, close the inbound firewall rule and the proxy route to n8n. The relay's public URL is the only thing the internet sees.",{"type":47,"tag":80,"props":887,"children":889},{"id":888},"hardening-that-still-matters",[890],{"type":56,"value":891},"Hardening that still matters",{"type":47,"tag":249,"props":893,"children":894},{},[895,905,915,948,966,976],{"type":47,"tag":253,"props":896,"children":897},{},[898,903],{"type":47,"tag":52,"props":899,"children":900},{},[901],{"type":56,"value":902},"Patch.",{"type":56,"value":904}," The relay does not fix CVE-2025-68613 or its follow-ups. Run a current release, not just 1.122.0.",{"type":47,"tag":253,"props":906,"children":907},{},[908,913],{"type":47,"tag":52,"props":909,"children":910},{},[911],{"type":56,"value":912},"Restrict workflow editors.",{"type":56,"value":914}," Both expression bugs need permission to create or modify workflows, and n8n's workaround is to limit that to fully trusted users.",{"type":47,"tag":253,"props":916,"children":917},{},[918,923,925,931,933,939,941,947],{"type":47,"tag":52,"props":919,"children":920},{},[921],{"type":56,"value":922},"Authenticate the sender.",{"type":56,"value":924}," Set endpoint authentication on the trigger, or verify the provider's HMAC signature with a ",{"type":47,"tag":92,"props":926,"children":928},{"href":927},"/docs/webhooks/auth/hmac/",[929],{"type":56,"value":930},"Webhook Relay function",{"type":56,"value":932},". See also ",{"type":47,"tag":92,"props":934,"children":936},{"href":935},"/blog/verify-webhook-signature/",[937],{"type":56,"value":938},"how to verify a webhook signature",{"type":56,"value":940}," and ",{"type":47,"tag":92,"props":942,"children":944},{"href":943},"/blog/webhook-security/",[945],{"type":56,"value":946},"webhook security best practices",{"type":56,"value":505},{"type":47,"tag":253,"props":949,"children":950},{},[951,956,958,964],{"type":47,"tag":52,"props":952,"children":953},{},[954],{"type":56,"value":955},"Filter before delivery.",{"type":56,"value":957}," Drop events you never act on with ",{"type":47,"tag":92,"props":959,"children":961},{"href":960},"/docs/webhooks/functions/filter-webhooks/",[962],{"type":56,"value":963},"filtering rules or a function",{"type":56,"value":965}," so n8n workflows see less untrusted input.",{"type":47,"tag":253,"props":967,"children":968},{},[969,974],{"type":47,"tag":52,"props":970,"children":971},{},[972],{"type":56,"value":973},"Run n8n with least privilege.",{"type":56,"value":975}," Restricted OS privileges and limited outbound network access reduce what a code-execution bug can reach, as the vendor advises.",{"type":47,"tag":253,"props":977,"children":978},{},[979,984],{"type":47,"tag":52,"props":980,"children":981},{},[982],{"type":56,"value":983},"Rotate stored credentials",{"type":56,"value":985}," if the instance was internet-reachable while unpatched.",{"type":47,"tag":48,"props":987,"children":988},{},[989,991,997,998,1004],{"type":56,"value":990},"The same pattern applies to other self-hosted tools; see ",{"type":47,"tag":92,"props":992,"children":994},{"href":993},"/blog/securing-jenkins/",[995],{"type":56,"value":996},"securing Jenkins",{"type":56,"value":940},{"type":47,"tag":92,"props":999,"children":1001},{"href":1000},"/blog/webhooks-in-ci-cd/",[1002],{"type":56,"value":1003},"receiving webhooks in CI/CD",{"type":56,"value":505},{"type":47,"tag":80,"props":1006,"children":1008},{"id":1007},"honest-limits",[1009],{"type":56,"value":1010},"Honest limits",{"type":47,"tag":48,"props":1012,"children":1013},{},[1014],{"type":56,"value":1015},"A relay narrows what is reachable. It does not make every n8n flaw irrelevant.",{"type":47,"tag":249,"props":1017,"children":1018},{},[1019,1036,1046,1056,1066],{"type":47,"tag":253,"props":1020,"children":1021},{},[1022,1027,1029,1034],{"type":47,"tag":52,"props":1023,"children":1024},{},[1025],{"type":56,"value":1026},"The webhook path can itself be vulnerable.",{"type":56,"value":1028}," CVE-2026-21858 involves form-based workflows and publicly accessible webhook and form endpoints. If your sender can reach a vulnerable workflow through the relay (Option B), a crafted request is still delivered. Verify the provider's signature at the relay with an ",{"type":47,"tag":92,"props":1030,"children":1031},{"href":927},[1032],{"type":56,"value":1033},"HMAC function",{"type":56,"value":1035}," so unsigned requests are rejected with a 401 before they reach n8n, forward only the specific paths you need, and patch.",{"type":47,"tag":253,"props":1037,"children":1038},{},[1039,1044],{"type":47,"tag":52,"props":1040,"children":1041},{},[1042],{"type":56,"value":1043},"Public forms are n8n's own surface.",{"type":56,"value":1045}," If you need n8n-hosted public form pages, the relay does not replace that listener. Treat those as exposed and keep them patched.",{"type":47,"tag":253,"props":1047,"children":1048},{},[1049,1054],{"type":47,"tag":52,"props":1050,"children":1051},{},[1052],{"type":56,"value":1053},"Users who need the editor from outside",{"type":56,"value":1055}," need a VPN, SSO-aware proxy or similar. The relay solves webhook delivery, not human access.",{"type":47,"tag":253,"props":1057,"children":1058},{},[1059,1064],{"type":47,"tag":52,"props":1060,"children":1061},{},[1062],{"type":56,"value":1063},"Authenticated attackers.",{"type":56,"value":1065}," Anyone with a legitimate account on an unpatched instance can still use CVE-2025-68613. The relay removes the public login prompt; it does not remove the bug.",{"type":47,"tag":253,"props":1067,"children":1068},{},[1069,1074],{"type":47,"tag":52,"props":1070,"children":1071},{},[1072],{"type":56,"value":1073},"The relay is a new trust point.",{"type":56,"value":1075}," Keep verifying signatures at n8n or at the relay.",{"type":47,"tag":80,"props":1077,"children":1079},{"id":1078},"next-step",[1080],{"type":56,"value":1081},"Next step",{"type":47,"tag":80,"props":1083,"children":1085},{"id":1084},"more-self-hosted-tools-that-are-public-only-for-webhooks",[1086],{"type":56,"value":1087},"More self-hosted tools that are public only for webhooks",{"type":47,"tag":249,"props":1089,"children":1090},{},[1091,1100,1109,1118],{"type":47,"tag":253,"props":1092,"children":1093},{},[1094],{"type":47,"tag":92,"props":1095,"children":1097},{"href":1096},"/blog/jenkins-vulnerabilities/",[1098],{"type":56,"value":1099},"Jenkins vulnerabilities exploited in the wild",{"type":47,"tag":253,"props":1101,"children":1102},{},[1103],{"type":47,"tag":92,"props":1104,"children":1106},{"href":1105},"/blog/teamcity-vulnerabilities/",[1107],{"type":56,"value":1108},"TeamCity CVE-2023-42793 and CVE-2024-27198",{"type":47,"tag":253,"props":1110,"children":1111},{},[1112],{"type":47,"tag":92,"props":1113,"children":1115},{"href":1114},"/blog/langflow-vulnerabilities/",[1116],{"type":56,"value":1117},"Langflow vulnerabilities, from CVE-2025-3248 on",{"type":47,"tag":253,"props":1119,"children":1120},{},[1121],{"type":47,"tag":92,"props":1122,"children":1124},{"href":1123},"/blog/kestra-security/",[1125],{"type":56,"value":1126},"Kestra security and CVE-2026-49869",{"type":47,"tag":48,"props":1128,"children":1129},{},[1130,1132,1139,1141,1145],{"type":56,"value":1131},"If your n8n is public today only so Webhook nodes can receive events, that is the first thing to change. ",{"type":47,"tag":92,"props":1133,"children":1136},{"href":1134,"rel":1135},"https://my.webhookrelay.com/register",[96],[1137],{"type":56,"value":1138},"Create a free Webhook Relay account",{"type":56,"value":1140},", follow the ",{"type":47,"tag":92,"props":1142,"children":1143},{"href":576},[1144],{"type":56,"value":579},{"type":56,"value":1146},", then close the inbound route.",{"type":47,"tag":1148,"props":1149,"children":1150},"style",{},[1151],{"type":56,"value":1152},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":1154,"depth":1154,"links":1155},3,[1156,1157,1158,1159,1163,1164,1165,1166],{"id":82,"depth":786,"text":85},{"id":308,"depth":786,"text":311},{"id":324,"depth":786,"text":327},{"id":553,"depth":786,"text":556,"children":1160},[1161,1162],{"id":565,"depth":1154,"text":568},{"id":719,"depth":1154,"text":722},{"id":888,"depth":786,"text":891},{"id":1007,"depth":786,"text":1010},{"id":1078,"depth":786,"text":1081},{"id":1084,"depth":786,"text":1087},"markdown","content:blog:n8n-security.md","content","blog/n8n-security.md","blog/n8n-security","md",{"loc":4},8,1793261997100]