The Developer Left the Door Open
When a developer builds a registration form, they write code that takes the submitted data and saves it to the database. The lazy way to do this — and the common way — is to pass the entire request body directly to the database object. Every field in the JSON becomes a field on the user record.
The frontend only sends username, email, and password. But the user record in the database also has a role field, a credits field, a verified field. The developer assumed nobody would send those. They were wrong.
The difference is one line of code. The vulnerable version trusts whatever fields you send. The secure version ignores everything except what it explicitly picks out.
A registration endpoint uses: const user = { ...req.body, id: nextId() }. You send {"username":"hacker","password":"pass","role":"admin"}. What happens?