How a missing HTML attribute can leak plain-text credentials during network throttling, and why Progressive Enhancement still matters in 2026.

While exploring a major production platform recently (400M USD in annual revenue), I stumbled upon an edge case that reminded me why Progressive Enhancement isn't just a "nice-to-have", it's a security requirement.
I noticed my credentials appearing in the browser's URL bar during a login attempt. As a developer, I was immediately concerned.
During a standard login flow on a Next.js-powered site, my browser sent a GET request containing my email and password as plain-text query parameters:
https://target-app.com/login?email=myemail@example.com&password=myactualpassword
I was using Brave browser on a throttled connection. Because the network was slow, the JavaScript bundles responsible for "hydrating" the page hadn't finished loading when I hit the "Log in" button.
In modern SSR (Server-Side Rendering) frameworks like Next.js or SvelteKit, the server sends a static HTML version of the page first, which is then "hydrated" by JavaScript to become interactive.
If a user interacts with a form before hydration is complete, the browser falls back to default HTML behavior. In this specific case:
1. The <form> tag in the raw HTML was missing the method="POST" attribute.
2. By default, browsers treat any form without a method as a GET request.
3. The browser took every inputfield and appended it to the URL.
Security triagers often classify this as a P5 (Informational) finding because it technically occurs on the "client-side". However, for a developer, the impact is real:
The fix is deceptively simple. Regardless of how much "magic" your framework (Next.js, SvelteKit, etc.) does with `onSubmit` handlers or Server Actions, your raw HTML must be secure.
The "Insecure" Way:
<form class="styling-classes" onSubmit={handleSubmit}>
<input name="password" type="password" />
<button type="submit">Login</button>
</form>
The Secure Way:
<form method="POST" class="styling-classes" onSubmit={handleSubmit}>
<input name="password" type="password" />
<button type="submit">Login</button>
</form>
By adding method="POST", you ensure that even if hydration fails, the browser will still perform a secure POST request rather than defaulting to GET.
This experience was a great reminder that as we move toward more complex system architectures and frameworks, we cannot ignore the fundamentals of the web.
Whether you're using SvelteKit (my personal favorite) or Next.js, always ensure your forms have a secure fallback. Don't let your users' security depend on how fast their JavaScript bundles load.
Please sign in to leave a comment.
No comments yet. Be the first to comment!