White paper WP-01
Forms that collect credentials you should never hold
Asking a customer for their password to another service is common, quietly catastrophic, and almost always avoidable. What goes wrong, why it survives internal review, and what to do instead.
- For
- Product owners, operations teams, and anyone who has ever built a form to make an internal process easier.
- Reading time
- About 4 minutes
- Published by
- Assumed Breach
Executive summary
Forms that ask a customer for their password to another service are rarely a deliberate decision. They are an operational shortcut, usually built in a form builder outside the codebase, so they never meet the design review, pull request or deployment that would have caught them.
The damage reaches well beyond the service the password was asked for. Stored credentials sit in plain text in exports, backups, notifications and connected tools, and because passwords are reused, each one is a plausible key to the person's email and more. Form builders also default to public links, so these forms are often reachable, and indexed, by anyone.
The fix is to never hold the credential: use delegated authorisation, or have the customer act themselves. If you already run a form like this, preserve the evidence first, then remove the field, restrict the form, notify the people affected, purge what you hold, and look for the others.
1. How it happens
Nobody decides to build a credential harvester. The sequence is almost always operational: a team needs to act on a customer's behalf on some third-party service, the service has no delegated access model that fits, and the quickest route is to ask the customer for their login. A field is added to a form that already exists. It solves the immediate problem on the day it ships.
It survives because it does not look like a security decision. The form is a marketing or operations artefact, built in a form builder rather than in the codebase, and it never passes in front of the people who would object. There is no pull request, no design review, and no deployment, which means none of the checkpoints that would normally catch it exist at all.
2. Why it is worse than it looks
The immediate exposure is that the credential is stored somewhere it should not be, usually in plain text, readable by everyone with access to the collecting account and by every integration connected to it. That alone is serious.
The larger exposure is reuse. A password given for one service is frequently the password for others, so the organisation has not merely acquired a credential for a third-party account. It has acquired a plausible credential for that person's email, and through it much of the rest of their life. The blast radius has nothing to do with the service the password was asked for.
There is also a durability problem. Once a credential is in a form platform, it is in exports, backups, notifications, and any tool wired to that platform. Deleting the visible copy does not reliably delete the others, which is why the correct response involves both purging and notifying rather than only purging.
3. The compounding failure: no boundary at all
Collection is often paired with a second mistake. The form is not access controlled. Form builders default to a public link because their primary use case is public. A form intended for a known group ends up on a page anyone can reach, and because it is embedded in a normal web page, search engines index it like any other content.
The signature of this failure is worth knowing: a form that receives far more views and starts than it has intended recipients, arriving with referrers from the public web rather than from the invitation that was supposed to be the only route in. Those numbers are visible in every mainstream form platform, and almost nobody looks at them.
4. What to do instead
The correct pattern is that you never hold the credential. Where the third party supports delegated authorisation, use it: the customer authenticates with the service directly and grants scoped access, which they can revoke without changing anything. Where the third party supports nothing of the kind, the honest answer is usually that the customer performs the action themselves, guided, rather than handing over the keys.
If a credential genuinely must be passed on, use a mechanism designed for the purpose, such as a one-time secret link that expires and is not retained. Never use a general-purpose form platform whose retention you do not control.
5. If you already have one
Preserve the current configuration and a full export before changing anything, and record the time of the change. Investigations and any notification obligation both depend on establishing what was exposed and for how long, and that evidence is destroyed by tidying up first.
Then remove the field, restrict the form, notify the people whose credentials you hold and tell them plainly to change that password anywhere it was reused, and purge the stored values once you have confirmed what you are required to retain. Notification is a legal question as much as a technical one; involve counsel early rather than after deciding.
Finally, sweep the rest. A team that built one of these has usually built more than one, and the others are in the same form platform.
Get the next write-up by email
New technical write-ups by email when we publish. No sales sequence, and every email has an unsubscribe link.
Prefer a feed? RSS. How we handle your address: privacy notice.
Want this checked against your own systems?
Tell us what you run and what worries you. We will say plainly whether a test would help.