Backend Security & the OWASP Top 10
The most common web application security risks from the OWASP Top 10, explained for backend developers with real examples.
Why backend security is your job
Every API you build is reachable by anyone on the internet — including attackers running automated scanners 24 hours a day. Frameworks help, but most real breaches come from a handful of predictable backend mistakes: weak authentication, missing authorization checks, injection, and leaked secrets.
The good news: if you understand the common risks, you can avoid most of them with habits, not heroics.
The OWASP Top 10
The OWASP Top 10 is the industry's reference list of the most critical web application security risks. These are the categories every backend developer should recognise:
| Risk | What goes wrong | Typical backend fix |
|---|---|---|
| Broken access control | Users reach data or actions they shouldn't (GET /orders/1043 shows someone else's order) |
Check ownership/permissions on every request, server-side |
| Cryptographic failures | Sensitive data stored or sent without proper protection | HTTPS everywhere, strong password hashing, encrypt sensitive fields |
| Injection | Untrusted input is executed as SQL, shell or template code | Parameterised queries, no string-built commands |
| Insecure design | Missing security thinking at the design stage | Threat modelling, rate limits, secure defaults |
| Security misconfiguration | Debug mode on, default passwords, verbose errors | Hardened configs, separate prod settings |
| Vulnerable components | Outdated libraries with known CVEs | Dependency scanning and regular updates |
| Authentication failures | Weak passwords, no rate limiting, broken sessions | Strong hashing, MFA, lockouts, secure sessions |
| Integrity failures | Untrusted updates, unsafe deserialization | Signed artifacts, never deserialize untrusted data |
| Logging & monitoring failures | Attacks go unnoticed | Log security events and alert on them |
| Server-Side Request Forgery (SSRF) | Your server is tricked into requesting internal URLs | Validate and allow-list outbound URLs |
Authentication vs authorization
Two words students often mix up:
- Authentication (AuthN) — who are you? Logging in with a password, a passkey, Google sign-in.
- Authorization (AuthZ) — what are you allowed to do? Can this user edit this post? Is this user an admin?
Most serious breaches are authorization bugs — the user is logged in, but the code forgets to check whether this user may access this record.
# Broken access control: any logged-in user can read any invoice
@app.get("/invoices/{invoice_id}")
def get_invoice(invoice_id: int, user = Depends(current_user)):
return db.get_invoice(invoice_id)
# Fixed: scope the query to the current user
@app.get("/invoices/{invoice_id}")
def get_invoice(invoice_id: int, user = Depends(current_user)):
invoice = db.get_invoice(invoice_id)
if invoice is None or invoice.owner_id != user.id:
raise HTTPException(status_code=404) # 404 avoids revealing that it exists
return invoice
Core security principles
- Never trust client input. Validate type, length, format and range on the server — the frontend's validation is only for user experience.
- Least privilege. Database users, API keys and services get only the permissions they need.
- Defense in depth. Several independent layers (validation, auth, rate limits, monitoring) so one mistake isn't fatal.
- Secure defaults. New endpoints should be private until made public deliberately.
- Fail closed. If an authorization check errors, deny access.
- Keep secrets out of code. Use environment variables or a secrets manager, never Git.
Security headers and HTTPS
- Serve everything over HTTPS and enable HSTS (
Strict-Transport-Security). - Set cookies with
Secure,HttpOnlyandSameSite. - Add
Content-Security-Policy,X-Content-Type-Options: nosniffand a strict CORS policy (never*with credentials).
What you'll learn in this tutorial
| Lesson | Skill |
|---|---|
| Password Hashing & Sessions | Store credentials safely and manage logins |
| JWT Explained | Use tokens correctly — and know their pitfalls |
| OAuth 2.0 & OpenID Connect | Implement "Sign in with…" and delegated access |
| SQL Injection, SSRF & Input Validation | Stop the classic injection attacks |
Common mistakes
- Checking permissions only in the UI. Attackers call your API directly.
- Returning detailed stack traces in production. They reveal paths, queries and versions.
- Rolling your own crypto. Use well-reviewed libraries.
- Logging passwords, tokens or full card numbers. Logs leak too.
Key takeaways
- The OWASP Top 10 is the checklist of the risks that matter most.
- Authentication proves identity; authorization decides access — check both on every request.
- Validate all input, apply least privilege, and keep secrets out of code.