@nuxt/ui: UAuthForm / UForm SSR markup omits `method`, leaking credentials via GET if submitted before hydration
### Summary `UForm` and `UAuthForm` render a server-side `<form>` element with no `method` and no `action` attribute, relying on a hydrated `@submit.prevent` handler to intercept submission. If a user submits the form before Vue hydration has attached the handler (autofill plus Enter on a slow network, JS bundle blocked by CSP or CDN failure, etc.), the browser performs the native default: a `GET` to the current URL with every named field, including `<input type="password">`, serialised into the query string. ### Details `src/runtime/components/Form.vue` (around the template's `<form>` element) emits: ```vue <component :is="parentBus ? 'div' : 'form'" :id="formId" ref="formRef" :class="ui({ class: [uiProp?.base, props.class] })" @submit.prevent="onSubmitWrapper" > ``` No `method`, no `action`. `@submit.prevent` is the only thing stopping native submission, and it only exists after hydration. `UAuthForm` composes `UForm` and inherits the same shape. The SSR snapshot of `UAuthForm` (`test/components/__snapshots__/AuthForm.spec.ts.snap`) shows the rendered markup, with `<input type="password" name="password">` inside a `<form>` that has no `method`. ### Proof of concept Reported by @nimonian: 1. Create a minimal Nuxt app with a `UAuthForm`. 2. Build for production and visit in a browser with network throttling at 4G or slower. 3. Enter credentials. 4. Submit (or let autofill + Enter fire before hydration). The URL becomes `/login?email=…&password=…`. Reproducible deterministically in Playwright by triggering submit immediately on `load`. ### Impact Any application using `UAuthForm` (or `UForm` with credential-shaped fields) as documented. The cleartext password lands in: - the address bar, - `window.history`, - the `Referer` header of every same-origin subresource fetched from the resulting URL, - access logs of any reverse proxy, CDN, or WAF that records request URLs. ### Patch Default the rendered `<form>` to `method="post"` so the pre-hydration fallback submits as POST rather than GET. Vue's `@submit.prevent` still intercepts the hydrated case; the attribute only matters in the race window. Applications that explicitly want native GET submission can opt back in by passing `method="get"`. ### Credit Reported by @nimonian. Originally filed as `GHSA-92g7-2fpq-hmq8` against `nuxt/nuxt`; moved here because the affected code lives in `@nuxt/ui`.
AI Analysis
Technical Summary
The vulnerability in @nuxt/ui's UForm and UAuthForm components arises because server-side rendered forms omit the method attribute and rely on a Vue hydration handler to prevent native form submission. If the form is submitted before hydration (e.g., due to slow network or JS blocking), the browser performs a default GET request, including sensitive fields like passwords in the URL query string. This leads to credential leakage via the URL, browser history, Referer headers, and logs. The recommended fix is to default the form's method attribute to POST to ensure safe fallback behavior prior to hydration.
Potential Impact
Credentials, including passwords, can be exposed in cleartext in the URL query string if a form is submitted before Vue hydration attaches the submit handler. This exposure affects the browser address bar, window history, Referer headers sent to same-origin resources, and any server or proxy logs that record URLs. This leakage risks unauthorized disclosure of sensitive authentication data.
Mitigation Recommendations
A patch is available that sets the form's method attribute to POST by default, preventing credential leakage during the hydration race window. Applications can opt back into GET submissions by explicitly specifying method="get". Users should upgrade to a version where this fix is applied or manually set method="post" on forms using UForm or UAuthForm to mitigate the issue.
@nuxt/ui: UAuthForm / UForm SSR markup omits `method`, leaking credentials via GET if submitted before hydration
Description
### Summary `UForm` and `UAuthForm` render a server-side `<form>` element with no `method` and no `action` attribute, relying on a hydrated `@submit.prevent` handler to intercept submission. If a user submits the form before Vue hydration has attached the handler (autofill plus Enter on a slow network, JS bundle blocked by CSP or CDN failure, etc.), the browser performs the native default: a `GET` to the current URL with every named field, including `<input type="password">`, serialised into the query string. ### Details `src/runtime/components/Form.vue` (around the template's `<form>` element) emits: ```vue <component :is="parentBus ? 'div' : 'form'" :id="formId" ref="formRef" :class="ui({ class: [uiProp?.base, props.class] })" @submit.prevent="onSubmitWrapper" > ``` No `method`, no `action`. `@submit.prevent` is the only thing stopping native submission, and it only exists after hydration. `UAuthForm` composes `UForm` and inherits the same shape. The SSR snapshot of `UAuthForm` (`test/components/__snapshots__/AuthForm.spec.ts.snap`) shows the rendered markup, with `<input type="password" name="password">` inside a `<form>` that has no `method`. ### Proof of concept Reported by @nimonian: 1. Create a minimal Nuxt app with a `UAuthForm`. 2. Build for production and visit in a browser with network throttling at 4G or slower. 3. Enter credentials. 4. Submit (or let autofill + Enter fire before hydration). The URL becomes `/login?email=…&password=…`. Reproducible deterministically in Playwright by triggering submit immediately on `load`. ### Impact Any application using `UAuthForm` (or `UForm` with credential-shaped fields) as documented. The cleartext password lands in: - the address bar, - `window.history`, - the `Referer` header of every same-origin subresource fetched from the resulting URL, - access logs of any reverse proxy, CDN, or WAF that records request URLs. ### Patch Default the rendered `<form>` to `method="post"` so the pre-hydration fallback submits as POST rather than GET. Vue's `@submit.prevent` still intercepts the hydrated case; the attribute only matters in the race window. Applications that explicitly want native GET submission can opt back in by passing `method="get"`. ### Credit Reported by @nimonian. Originally filed as `GHSA-92g7-2fpq-hmq8` against `nuxt/nuxt`; moved here because the affected code lives in `@nuxt/ui`.
CVSS v4.0
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
The vulnerability in @nuxt/ui's UForm and UAuthForm components arises because server-side rendered forms omit the method attribute and rely on a Vue hydration handler to prevent native form submission. If the form is submitted before hydration (e.g., due to slow network or JS blocking), the browser performs a default GET request, including sensitive fields like passwords in the URL query string. This leads to credential leakage via the URL, browser history, Referer headers, and logs. The recommended fix is to default the form's method attribute to POST to ensure safe fallback behavior prior to hydration.
Potential Impact
Credentials, including passwords, can be exposed in cleartext in the URL query string if a form is submitted before Vue hydration attaches the submit handler. This exposure affects the browser address bar, window history, Referer headers sent to same-origin resources, and any server or proxy logs that record URLs. This leakage risks unauthorized disclosure of sensitive authentication data.
Mitigation Recommendations
A patch is available that sets the form's method attribute to POST by default, preventing credential leakage during the hydration race window. Applications can opt back into GET submissions by explicitly specifying method="get". Users should upgrade to a version where this fix is applied or manually set method="post" on forms using UForm or UAuthForm to mitigate the issue.
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-gj2h-2fpw-fhv9
- Osv Schema Version
- 1.4.0
- Aliases
- []
- Ecosystems
- ["npm"]
- Database Specific Severity
- MODERATE
- Cvss Version
- 4.0
Threat ID: 6a46ecb527e9c7971943c89d
Added to database: 07/02/2026, 22:56:53 UTC
Last enriched: 07/02/2026, 23:09:33 UTC
Last updated: 07/30/2026, 07:25:27 UTC
Views: 33
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
External Links
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.