Every portal we take over gets a security review before it goes live. These are the findings that recur most often, in roughly the order we find them.
1. Broken object-level authorisation
The single most common serious issue. The UI only shows a user their own invoices, but /api/invoices/4471 returns anyone's. Authorisation must be enforced in the query — scope every read to the authenticated principal, not filtered after fetching.
2. Sessions that never really end
Logout that only clears client state leaves the token valid. Tokens with no expiry. No revocation when a user is deactivated. Check that a disabled account cannot use a token issued five minutes earlier.
3. File uploads accepted on trust
Extension checks instead of content sniffing, no size limit, files written inside the web root and served with a guessed content type. An "invoice.pdf" that is actually HTML becomes stored XSS.
4. No rate limiting on anything that matters
Login, password reset, OTP verification and any endpoint that sends an email or SMS. Without limits these are free credential-stuffing and free spend.
5. Over-exposed API responses
An endpoint returning the full user record — password hash, internal flags, other users' identifiers — because it serialises the ORM entity directly. Always project explicitly into a response shape.
6. Errors that teach the attacker
"User not found" versus "Incorrect password" tells an attacker which accounts exist. Return one message for both.
7. Logging that cannot support an investigation
Nothing recorded for authentication events, permission changes or data exports. When something does go wrong, the first question is "what did they access?" — and there needs to be an answer.
None of this is exotic. Competent teams ship these because security review sits at the end of the plan, where the schedule pressure is highest. Move it earlier.