{"id":"GHSA-r9jc-w898-3fv6","kind":"vulnerability","aliases":["GHSA-r9jc-w898-3fv6"],"related":[],"title":"Nuxt payload URL generation has quadratic cost for repeated slashes in the request path","description":"### Summary\n\nNuxt strips trailing slashes from the request path with a regular expression whose cost grows quadratically with the length of a run of consecutive slashes. A single unauthenticated request with a long run of slashes can occupy the server's event loop for a noticeable time, delaying every other request handled by the same process.\n\n### Impact\n\nWhen a page is rendered with payload extraction (any route covered by an `isr`, `swr` or `cache` route rule), Nuxt builds the `_payload.json` URL from the raw request path. A path such as `/blog/a` followed by 16,000 slashes and `x`, which fits within Node's default header size limit, takes roughly 0.1 to 0.4 seconds of synchronous CPU time per request, depending on hardware. Concurrent requests to the same process wait for it to finish, so a modest request rate can keep a process saturated.\n\nAn app is affected if it uses Nuxt 4.6.0 or later with server-side rendering and has a route rule like:\n\n```ts\nexport default defineNuxtConfig({\n  routeRules: {\n    '/blog/**': { swr: true },\n  },\n})\n```\n\nThe same pattern is also reachable through the opt-in `experimental.early404` option, for any request path.\n\nApps without `isr`, `swr` or `cache` route rules and without `experimental.early404` are not affected, nor are fully prerendered or client-only apps. The cost is bounded by the maximum request path length, so a reverse proxy with a smaller header limit reduces it further. There is no confidentiality or integrity impact.\n\n### Patches\n\nFixed in `nuxt` 4.6.4. Trailing slashes are now removed with a linear scan instead of a regular expression.\n\n### Workarounds\n\nReject request paths containing repeated slashes before they reach the renderer, for example at the reverse proxy or with a server middleware:\n\n```ts\n// server/middleware/reject-repeated-slashes.ts\nexport default defineEventHandler((event) => {\n  if (event.path.split('?')[0]!.includes('//')) {\n    throw createError({ statusCode: 404 })\n  }\n})\n```\n\nIf you use `experimental.early404`, you can also disable it until you upgrade.\n\n### Credits\n\nThanks to cryptofox9 for reporting this issue.","summary":"Nuxt 4.6.0 through 4.6.3 strips trailing slashes with a regular expression whose cost grows quadratically with long runs of slashes. A single unauthenticated request with a long run of slashes can block the server's event loop for a fraction of a second, delaying other requests in the same process.","severity":"low","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"nuxt","fixed":["4.6.4"],"affected":">= 4.6.0, < 4.6.4","ecosystem":"npm"}],"ecosystems":["npm"],"tags":["cwe-1333","node","nuxt","package","self-hosted"],"not_affected_if":["client-only","default-config","static-export"],"how_to_check":"- Check the installed `nuxt` version in `package.json` and the lockfile; affected if it is `>= 4.6.0` and `< 4.6.4`.\n- Look for `isr`, `swr` or `cache` entries in `routeRules`, or `experimental.early404` in `nuxt.config`; the issue needs one of these to apply.","fix":"- `nuxt` `4.6.4`","status":"open","published_at":"2026-11-02T20:59:19+00:00","first_seen_at":"2026-11-09T22:53:16+00:00","triaged_at":"2026-11-09T22:58:48+00:00","updated_at":"2026-11-09T22:58:48+00:00","category":"package","confidence":0.9,"triage":{"at":"2026-11-09T22:58:48Z","model":"claude-haiku-5-5","output":{"fix":"- `nuxt` `4.6.4`","reach":"internet","title":"Nuxt: repeated slashes in request path cause slow server processing","impact":"low","summary":"Nuxt 4.6.0 through 4.6.3 strips trailing slashes with a regular expression whose cost grows quadratically with long runs of slashes. A single unauthenticated request with a long run of slashes can block the server's event loop for a fraction of a second, delaying other requests in the same process.","audience":"developers","category":"package","nicknames":[],"who_cares":["nuxt","self-hosted","node"],"confidence":0.9,"fix_status":"available","needs_auth":"no","worst_case":"Single request slows server processing, delaying other requests on same process","analyst_note":"","how_to_check":"- Check the installed `nuxt` version in `package.json` and the lockfile; affected if it is `>= 4.6.0` and `< 4.6.4`.\n- Look for `isr`, `swr` or `cache` entries in `routeRules`, or `experimental.early404` in `nuxt.config`; the issue needs one of these to apply.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["static-export","client-only","default-config"],"who_is_affected":"Apps using Nuxt 4.6.0 or later with server-side rendering and a route rule that uses `isr`, `swr` or `cache`, or with `experimental.early404` enabled. Prerendered apps, client-only apps, and apps without those route rules or options are not affected. The impact is limited to denial of service by slowing the process; there is no data exposure or integrity impact.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000822,"input_tokens":5267,"output_tokens":590,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-1333':27B '/blog':254C '/blog/a':174C '0':376C '0.1':193C '0.4':195C '000':178C '16':177C '3fv6':19A,24A '4.6.0':35B,235C '4.6.3':37B '4.6.4':330C '404':381C 'affect':230C,287C 'also':261C,388C 'app':228C,274C,296C 'block':65B 'bound':300C 'build':161C 'cach':157C,279C 'client':294C 'client-on':293C 'concurr':206C 'confidenti':322C 'consecut':108C 'contain':349C 'cost':7A,46B,98C,298C 'cover':151C 'cpu':199C 'createerror':379C 'credit':394C 'cryptofox9':397C 'cwe':26B 'default':187C,251C,371C 'defineeventhandl':372C 'definenuxtconfig':252C 'delay':77B,131C 'depend':203C 'disabl':389C 'event':69B,125C,373C 'event.path.split':375C 'everi':132C 'exampl':358C 'experimental.early404':268C,284C,385C 'export':250C,370C 'express':44B,96C,344C 'extract':148C 'finish':216C 'fit':183C 'fix':327C 'follow':175C 'fraction':73B 'fulli':290C 'generat':4A 'ghsa':16A,21A 'ghsa-r9jc-w898-3fv6':15A,20A 'grow':47B,99C 'handl':135C 'hardwar':205C 'header':188C,314C 'host':33B 'impact':140C,325C 'includ':377C 'instead':340C 'integr':324C 'isr':154C,276C 'issu':401C 'keep':223C 'later':237C 'length':103C,306C 'like':248C 'limit':190C,315C 'linear':338C 'long':50B,60B,116C 'loop':70B,126C 'maximum':303C 'middlewar':367C 'modest':219C 'node':28B,185C 'notic':129C 'nuxt':1A,25A,29B,34B,85C,160C,234C,329C 'occupi':121C 'opt':266C 'opt-in':265C 'option':269C 'packag':30B 'page':143C 'patch':326C 'path':14A,92C,169C,171C,273C,305C,348C 'pattern':259C 'payload':2A,147C 'payload.json':163C 'per':201C 'prerend':291C 'process':83B,139C,211C,225C 'proxi':310C,362C 'quadrat':6A,48B,100C 'r9jc':17A,22A 'rate':221C 'raw':167C 'reach':354C 'reachabl':262C 'reduc':316C 'regular':43B,95C,343C 'reject':346C 'remov':335C 'render':145C,242C,356C 'repeat':9A,350C 'report':399C 'request':13A,57B,79B,91C,113C,134C,168C,202C,207C,220C,272C,304C,347C 'revers':309C,361C 'rough':192C 'rout':150C,158C,246C,280C 'routerul':253C 'rule':159C,247C,281C 'run':51B,61B,106C,117C 'satur':226C 'scan':339C 'second':76B,196C 'self':32B 'self-host':31B 'server':67B,123C,240C,366C 'server-sid':239C 'server/middleware/reject-repeated-slashes.ts':369C 'side':241C 'singl':55B,111C 'size':189C 'slash':10A,40B,53B,63B,88C,109C,119C,179C,332C,351C 'smaller':313C 'statuscod':380C 'strip':38B,86C 'summari':84C 'swr':155C,255C,277C 'synchron':198C 'take':191C 'thank':395C 'throw':378C 'time':130C,200C 'trail':39B,87C,331C 'true':256C 'ts':249C,368C 'unauthent':56B,112C 'upgrad':393C 'url':3A,164C 'use':233C,384C 'w898':18A,23A 'wait':212C 'whose':45B,97C 'within':184C 'without':275C,283C 'workaround':345C 'x':181C","nicknames":[],"mitigations":[],"who_affected":"Apps using Nuxt 4.6.0 or later with server-side rendering and a route rule that uses `isr`, `swr` or `cache`, or with `experimental.early404` enabled. Prerendered apps, client-only apps, and apps without those route rules or options are not affected. The impact is limited to denial of service by slowing the process; there is no data exposure or integrity impact.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["nuxt"],"ptokens":["nuxt"],"labels":["cwe1333","low","node","npm","nuxt","package","selfhosted"],"campaign_type":null,"search_a":"'3fv6':19A,24A 'cost':7A 'generat':4A 'ghsa':16A,21A 'ghsa-r9jc-w898-3fv6':15A,20A 'nuxt':1A,25A 'path':14A 'payload':2A 'quadrat':6A 'r9jc':17A,22A 'repeat':9A 'request':13A 'slash':10A 'url':3A 'w898':18A,23A","search_b":"'-1333':27B '4.6.0':35B '4.6.3':37B 'block':65B 'cost':46B 'cwe':26B 'delay':77B 'event':69B 'express':44B 'fraction':73B 'grow':47B 'host':33B 'long':50B,60B 'loop':70B 'node':28B 'nuxt':29B,34B 'packag':30B 'process':83B 'quadrat':48B 'regular':43B 'request':57B,79B 'run':51B,61B 'second':76B 'self':32B 'self-host':31B 'server':67B 'singl':55B 'slash':40B,53B,63B 'strip':38B 'trail':39B 'unauthent':56B 'whose':45B","search_c":"'/blog':254C '/blog/a':174C '0':376C '0.1':193C '0.4':195C '000':178C '16':177C '4.6.0':235C '4.6.4':330C '404':381C 'affect':230C,287C 'also':261C,388C 'app':228C,274C,296C 'bound':300C 'build':161C 'cach':157C,279C 'client':294C 'client-on':293C 'concurr':206C 'confidenti':322C 'consecut':108C 'contain':349C 'cost':98C,298C 'cover':151C 'cpu':199C 'createerror':379C 'credit':394C 'cryptofox9':397C 'default':187C,251C,371C 'defineeventhandl':372C 'definenuxtconfig':252C 'delay':131C 'depend':203C 'disabl':389C 'event':125C,373C 'event.path.split':375C 'everi':132C 'exampl':358C 'experimental.early404':268C,284C,385C 'export':250C,370C 'express':96C,344C 'extract':148C 'finish':216C 'fit':183C 'fix':327C 'follow':175C 'fulli':290C 'grow':99C 'handl':135C 'hardwar':205C 'header':188C,314C 'impact':140C,325C 'includ':377C 'instead':340C 'integr':324C 'isr':154C,276C 'issu':401C 'keep':223C 'later':237C 'length':103C,306C 'like':248C 'limit':190C,315C 'linear':338C 'long':116C 'loop':126C 'maximum':303C 'middlewar':367C 'modest':219C 'node':185C 'notic':129C 'nuxt':85C,160C,234C,329C 'occupi':121C 'opt':266C 'opt-in':265C 'option':269C 'page':143C 'patch':326C 'path':92C,169C,171C,273C,305C,348C 'pattern':259C 'payload':147C 'payload.json':163C 'per':201C 'prerend':291C 'process':139C,211C,225C 'proxi':310C,362C 'quadrat':100C 'rate':221C 'raw':167C 'reach':354C 'reachabl':262C 'reduc':316C 'regular':95C,343C 'reject':346C 'remov':335C 'render':145C,242C,356C 'repeat':350C 'report':399C 'request':91C,113C,134C,168C,202C,207C,220C,272C,304C,347C 'revers':309C,361C 'rough':192C 'rout':150C,158C,246C,280C 'routerul':253C 'rule':159C,247C,281C 'run':106C,117C 'satur':226C 'scan':339C 'second':196C 'server':123C,240C,366C 'server-sid':239C 'server/middleware/reject-repeated-slashes.ts':369C 'side':241C 'singl':111C 'size':189C 'slash':88C,109C,119C,179C,332C,351C 'smaller':313C 'statuscod':380C 'strip':86C 'summari':84C 'swr':155C,255C,277C 'synchron':198C 'take':191C 'thank':395C 'throw':378C 'time':130C,200C 'trail':87C,331C 'true':256C 'ts':249C,368C 'unauthent':112C 'upgrad':393C 'url':164C 'use':233C,384C 'wait':212C 'whose':97C 'within':184C 'without':275C,283C 'workaround':345C 'x':181C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-02T20:59:19+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-r9jc-w898-3fv6","url":"https://github.com/nuxt/nuxt/security/advisories/GHSA-r9jc-w898-3fv6","severity":"low","published_at":"2026-11-02T20:59:19+00:00","modified_at":"2026-11-02T20:59:19+00:00","first_seen_at":"2026-11-09T22:53:16+00:00","fetched_at":"2026-11-09T22:53:16+00:00","note":null}],"documents":[{"id":110431,"url":"https://github.com/nuxt/nuxt/security/advisories/GHSA-r9jc-w898-3fv6","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}