When New Accounts Are Born as Admin
Self-registration that trusts a client role field or defaults new accounts to admin hands attackers privilege on signup. Here is the pattern and the fix.
What this is
A signup privilege-default vulnerability is a self-registration flow that hands new accounts more power than they should ever have. It takes three forms, and we see all three: a flow that trusts a role field the client sent and copies it into the account’s permissions; a flow that defaults every new account to a high-privilege role; and a flow that lets anyone self-provision into a privileged tenant. In each case the attacker does not escalate privilege after getting in. They register, and they are already in.
This is one of the highest-severity findings we report, because it collapses the whole authorization model in a single request. There is no chain to build. The account creation endpoint - the one surface a team most wants open to the public - is the exploit.
Why it keeps happening
Registration sits at an awkward seam. It is the one authenticated action a system must let unauthenticated strangers perform, and it writes the record that every later permission check will trust. Get the defaults wrong there and every downstream check faithfully enforces the wrong answer.
The most common cause is that the bug is in configuration, not code. A platform ships as several apps built from a shared codebase. One app is meant to allow public signup; another is not. The signup toggle gets left in the wrong state on the wrong app, and a registration flow that was safe by design on one deployment is wide open on the next. Nothing in the code looks wrong, because the code is the same code that is correct elsewhere.
Mass assignment has a different root: convenience. A framework that binds request fields straight to a model saves the developer from writing out each field by hand. It also, silently, lets the request name fields the developer never intended to expose - including the role. The signup form only shows email and password, so the role field is invisible in the UI and easy to forget exists in the payload. An attacker who reads the request does not forget.
And the high-privilege default is usually a leftover from early development, when the first accounts needed to be admins so the team could build. The default never got lowered before launch, and the account that seeds itself as admin is now anyone who signs up.
How the attack works
The mechanism is short by nature:
- Find the signup endpoint. Every product with accounts has one, and it is reachable by definition.
- Inspect the registration request. The attacker reads the real payload the form sends, not the fields the form displays. Where mass assignment is the flaw, they add a
rolefield -"role": "admin"- and submit it alongside the normal ones. - Register, then check what you got. They create the account and look at the privileges attached to it. Where the client role was trusted, the account is now admin. Where the default was high, they did not even need to send a role. Where the tenant was unscoped, they are inside someone else’s tenant with the data that comes with it.
No exploitation follows. The account they were handed is the finding.
What it looks like in the wild
We have found this across products with nothing in common but a public registration flow.
-
A student-housing CRM ran open self-registration that auto-granted the top executive role. Anyone who signed up landed with the highest privilege in the system, no manipulation required - the default itself was the vulnerability. Full teardown: New Accounts Born as Executives.
-
A customer-support AI startup defaulted new users to ADMIN, and its social-login path trusted the client to say who it was. A normal sign-in produced an administrative account. The login was real; what it created was the problem. Full teardown: The Social Login That Trusted the Client.
-
An AI-accounting fintech copied a client-supplied role straight into account permissions. A registration payload carrying
role="admin"was written through by a database trigger, so the account came out of signup with administrative rights the form never offered. Full teardown: The Signup Form That Made Me an Admin. -
A coliving marketplace left open signup defaulting to an operator role, and its email verification was cosmetic - the account worked whether or not the address was confirmed. Two weak controls stacked: a high default and a verification step that verified nothing.
-
A customer-success AI tool ran open signup with no tenant scoping, so a self-registered account could reach across tenants and read user data that belonged to other customers. The signup was open and the boundary that should have contained it was not there.
The consistent theme: the account-creation endpoint is meant to be public, so it gets the least suspicion, and a wrong default or a trusted field turns the most-open surface into the most-privileged one.
How to tell if you are exposed
A short self-check:
- Register a fresh account and read exactly what role and tenant it received. If a brand-new account holds any privilege beyond the minimum, your default is too high.
- Capture your own registration request and add fields the form does not show -
role,is_admin,tenant_id,permissions. Submit them. If any change lands on the account, the server is trusting the client. - Confirm which of your deployments have self-registration enabled, and whether every one of them is meant to. Look specifically for a shared codebase where signup is correctly off on one app and wrongly on for another.
- Register with an unverified email and see whether the account can act before verification. If it can, verification is cosmetic.
How to fix it
- The server assigns the role, never the client. Role and tenant are set server-side from trusted context, never read from the registration payload. The client cannot name its own privileges.
- Default new accounts to least privilege. Every new account starts with the minimum that lets the product work. Elevation is a separate, authorized, audited action - never a signup default.
- Reject unexpected fields. Bind registration to an explicit allow-list of fields. A payload that carries
roleorpermissionsis rejected, not silently absorbed. Turn off blanket mass assignment. - Gate self-registration and mean it. Confirm signup is enabled only where it should be, on every deployment. Enforce email verification as a real gate that blocks action until the address is confirmed, not a step that logs but does not stop.
The takeaway
The account-creation endpoint is the one door you deliberately leave open to strangers, which is exactly why its defaults have to be the strictest in the system. If the client can name its own role, or a new account is born as admin, registration is not a signup flow - it is a privilege giveaway. See this pattern in the field in New Accounts Born as Executives and its siblings.
Frequently asked
What is a signup privilege-default vulnerability?
What is mass assignment in registration?
How do you secure a signup flow?
This is one finding from a harness that runs continuously. See how Greywatch finds, proves, and fixes them.
How it works →



