The OWASP Top 10, explained with the code that causes each one
The Top 10 is a list of categories, not bugs. Here is what each one looks like in a real codebase.
Before launch, verify: authentication and session handling, authorisation enforced at the data layer, input validation on every endpoint, output encoding, security headers, dependency and secret hygiene, rate limiting, secure file uploads, error handling that does not leak internals, and logging that would let you investigate an incident.
Every request must be checked against the current user's permissions at the point the data is accessed, not in the UI or in middleware alone.
// Vulnerable: any authenticated user can read any invoice
const invoice = await db.invoice.findUnique({ where: { id } });
// Correct: ownership is part of the query
const invoice = await db.invoice.findFirst({
where: { id, organisationId: session.organisationId },
});
if (!invoice) notFound(); // do not reveal that it existsBefore launch, after any significant change to authentication or authorisation, and at least annually. Dependency scanning should run continuously in CI.
Attacks are automated and indiscriminate. A small site with a contact form and a login is scanned by bots within hours of going live; nobody has to target you specifically.
If you handle payments, personal data at scale, or have enterprise customers asking, yes. Fix the checklist items first so the engagement finds real issues rather than obvious ones.
Authorisation checks at the data layer. Broken access control is consistently the most prevalent serious vulnerability class in real applications.
ROVQIX Engineering
Engineering team, ROVQIX
The ROVQIX engineering team builds and maintains web platforms, APIs and infrastructure for clients across SaaS, ecommerce and enterprise. These notes come out of real production work — deploys, incidents, migrations and audits.
ROVQIXdesigns and builds production web platforms — Next.js front ends, Node.js APIs and the infrastructure behind them. Tell us what you're building and we'll scope it with you.
The Top 10 is a list of categories, not bugs. Here is what each one looks like in a real codebase.
The sessions-versus-JWT argument is really an argument about revocation. Decide how fast you need to be able to log someone out.
Six headers, most of them one line each. They will not fix a vulnerability, but several of them turn one into a non-event.
No spam. Just the occasional case study and craft breakdown.