0 Let's Talk

Security

Web Application Security: Using the OWASP Top 10 as Your Checklist

The OWASP Top 10 is the most widely used reference for web application risk. This guide turns each 2021 category into practical controls your team can build, test and verify, and explains what changed in the 2025 edition.

10 min read Adriel Corp Team
Developer reviewing code on a laptop with a padlock icon representing web application security
Photo: Yuri Samoilov / Wikimedia Commons, CC BY 3.0

Most web application breaches do not rely on exotic zero-day exploits. They exploit familiar mistakes: a missing permission check, an unpatched library, a password stored with a weak hash, an error message that reveals too much. The OWASP Top 10 exists precisely to catalogue those recurring mistakes, and for any team building or buying software it remains the most practical starting point for web application security.

In this guide we treat the OWASP Top 10 (2021) as a working checklist rather than a poster on the wall. For each category we explain what goes wrong in plain language, how it typically shows up in real business applications, and which controls actually prevent it. We finish with what changed in the newer 2025 edition and how to build these checks into your development lifecycle so security is not a last-minute scramble.

Whether you are a CTO reviewing a supplier, a business owner commissioning a new portal or a developer hardening an existing system, this is the list to work through.

What the OWASP Top 10 is, and what it is not

The OWASP Top 10 is published by the Open Worldwide Application Security Project, a non-profit foundation that produces free, vendor-neutral security resources. It ranks broad categories of risk using vulnerability data contributed by security firms and a survey of practitioners. Each category groups related weaknesses, catalogued as Common Weakness Enumerations (CWEs).

Two caveats matter. First, it is an awareness document, not a complete standard. An application can avoid all ten categories and still have serious flaws in its business logic. Second, it describes categories, not tests. To turn it into verifiable requirements, pair it with the OWASP Application Security Verification Standard (ASVS), which defines testable controls at different assurance levels.

Even so, if your team can demonstrate solid controls for every item below, you will have closed off the routes attackers use most often.

The OWASP Top 10 (2021) at a glance

Category What goes wrong Core controls
A01 Broken Access Control Users can act outside their intended permissions Deny by default, server-side authorisation on every request, ownership checks
A02 Cryptographic Failures Sensitive data exposed through weak or missing encryption TLS everywhere, strong password hashing, managed keys
A03 Injection Untrusted input interpreted as code or commands (including XSS) Parameterised queries, output encoding, input validation
A04 Insecure Design Missing or ineffective security controls by design Threat modelling, abuse cases, secure design patterns
A05 Security Misconfiguration Default settings, verbose errors, open storage, missing headers Hardened, repeatable configuration as code
A06 Vulnerable and Outdated Components Known-vulnerable libraries, frameworks or runtimes Inventory, automated dependency scanning, patching cadence
A07 Identification and Authentication Failures Weak login, session and credential handling MFA, rate limiting, secure session management
A08 Software and Data Integrity Failures Untrusted updates, pipelines or deserialised data Signed artefacts, protected CI/CD, safe deserialisation
A09 Security Logging and Monitoring Failures Attacks go undetected or cannot be investigated Security event logging, alerting, incident response
A10 Server-Side Request Forgery (SSRF) Server tricked into fetching attacker-chosen URLs Allow-lists, network segmentation, URL validation

Access control and authentication (A01 and A07)

A01 Broken Access Control

Broken access control sits at the top of the 2021 list for good reason. Typical examples include changing an ID in a URL from /invoices/1042 to /invoices/1043 and seeing another customer’s invoice (an insecure direct object reference), calling an admin API endpoint that the interface merely hides, or a regular user modifying a hidden form field to escalate their role.

Controls that work:

  • Deny by default. Every route and API endpoint should require an explicit authorisation rule; anything not explicitly allowed is refused.
  • Enforce on the server. Hiding a button in the user interface is not access control. Check permissions in the backend on every request.
  • Check ownership, not just role. Being a “customer” does not entitle you to every customer record. Scope queries to the authenticated user or tenant.
  • Centralise the logic. Use the framework’s policy or permission system, such as Laravel policies and gates, Django permissions or ASP.NET Core authorisation policies, rather than scattering ad hoc checks.
  • Write negative tests that prove a user cannot access another user’s data.

A07 Identification and Authentication Failures

This covers weak passwords, credential stuffing, poor session handling and flawed account recovery. Offer multi-factor authentication, and require it for administrators. Rate-limit and monitor login attempts. Check new passwords against lists of known-breached passwords rather than imposing arbitrary complexity rules. Regenerate session identifiers on login, set cookies with Secure, HttpOnly and an appropriate SameSite attribute, and make sure logout and password changes invalidate existing sessions. Where possible, rely on your framework’s mature authentication components or a reputable identity provider instead of building your own.

Protecting data and handling untrusted input (A02, A03 and A10)

A02 Cryptographic Failures

Formerly called “Sensitive Data Exposure”, this category focuses on the root cause: cryptography that is missing, weak or misused. Serve everything over TLS and enable HTTP Strict Transport Security. Hash passwords with an algorithm designed for the purpose, such as Argon2, bcrypt or PBKDF2 with appropriate work factors, never with plain or fast hashes. Encrypt sensitive data at rest, keep keys in a managed service such as Azure Key Vault or AWS KMS rather than in source code, and do not collect or retain personal information you do not need.

A03 Injection

Injection happens when untrusted input is sent to an interpreter as part of a command or query. SQL injection is the classic example, but the category also covers OS command injection, LDAP injection and, since 2021, cross-site scripting (XSS). The fix is to keep data and code separate:

  • Use parameterised queries or your ORM’s query builder. Eloquent, the Django ORM and Entity Framework parameterise by default; the risk returns when developers concatenate strings into raw SQL.
  • Rely on context-aware output encoding. Blade, Django templates and Razor escape output by default, so treat every use of “raw” or “safe” output as a code review red flag.
  • Add a Content Security Policy header as a second line of defence against XSS.
  • Validate input against strict allow-lists for format, length and type.

A10 Server-Side Request Forgery

SSRF arises when an application fetches a URL supplied by the user, for example to import an image, preview a link or call a webhook. An attacker supplies an internal address instead and uses your server to reach systems that are not exposed to the internet, including cloud metadata endpoints that may reveal credentials. Validate destinations against an allow-list, block private and link-local address ranges after DNS resolution, disable unnecessary redirects, and segment the network so web servers cannot reach sensitive internal services. On AWS, requiring IMDSv2 for instance metadata reduces one common SSRF impact.

Key takeaway: Modern frameworks protect you from many OWASP Top 10 risks by default. Most vulnerabilities appear where developers bypass those defaults: raw SQL, unescaped output, custom authentication or hand-rolled permission checks. Make every bypass visible in code review.

Design, configuration and dependencies (A04, A05 and A06)

A04 Insecure Design

Introduced in 2021, this category recognises that some flaws cannot be fixed by perfect implementation because the design itself is unsafe. Examples include a password reset flow based on guessable security questions, or a voucher system that allows unlimited redemptions because nobody considered abuse. The remedy is to think about security before coding: run lightweight threat modelling sessions, write abuse cases alongside user stories (“as an attacker, I want to reuse a voucher code”), and apply proven patterns for things like payments and multi-tenancy. In our process this belongs firmly in the Structuring Phase, where the system’s architecture is defined.

A05 Security Misconfiguration

Debug mode left on in production, default admin credentials, directory listing, publicly readable storage buckets, permissive CORS rules and verbose stack traces all fall here, as does XML External Entity (XXE) processing. Treat configuration as code: define environments through infrastructure as code, keep production settings in version control (secrets excluded), and apply security headers consistently. Automated configuration checks in your pipeline catch drift before it reaches users.

A06 Vulnerable and Outdated Components

Modern applications are mostly third-party code. If you cannot list your dependencies and their versions, you cannot know when one of them becomes a risk. Maintain a software bill of materials, enable automated dependency scanning (for example GitHub Dependabot, composer audit, pip-audit or npm audit), track the support lifecycle of your framework and runtime, and schedule regular upgrade work rather than waiting for an emergency. Unsupported frameworks are a common finding when we audit older systems.

Integrity, logging and monitoring (A08 and A09)

A08 Software and Data Integrity Failures

This category covers code and data that are trusted without verification: auto-update mechanisms without signature checks, scripts loaded from untrusted CDNs without Subresource Integrity, insecure deserialisation, and, increasingly, compromised CI/CD pipelines. Protect your build pipeline as carefully as production. Restrict who can modify workflows, require reviews on protected branches, pin third-party actions and packages to known versions, and use short-lived credentials for deployments. Our guide to CI/CD pipelines for small teams covers these practices in more detail.

A09 Security Logging and Monitoring Failures

If an attacker probes your login page for a week and nobody notices, every other control is weakened. Log authentication events, access control failures, input validation failures and high-value transactions with enough context to investigate, but without writing passwords, tokens or unnecessary personal information to logs. Centralise logs, protect them from tampering, and alert on suspicious patterns. Just as importantly, agree in advance who responds to an alert and how.

For South African organisations this connects directly to the Protection of Personal Information Act. Section 19 of POPIA requires appropriate, reasonable technical and organisational measures to secure personal information, and section 22 requires notification of the Information Regulator and affected data subjects when there are reasonable grounds to believe personal information has been accessed by an unauthorised person. You cannot meet that obligation if you cannot detect a compromise in the first place.

What changed in the OWASP Top 10:2025

OWASP has since published a 2025 edition of the Top 10. Much of the 2021 list carries forward, so work done against it is not wasted, but there are notable changes:

  • Broken Access Control remains first, and Server-Side Request Forgery is now folded into it rather than standing alone.
  • Security Misconfiguration moves up to second place.
  • Software Supply Chain Failures is a new, broader category that expands on the old “Vulnerable and Outdated Components”, covering the wider ecosystem of dependencies, build systems and distribution.
  • Mishandling of Exceptional Conditions is a new category covering improper error handling, failing open and similar logic flaws when systems meet unexpected states.
  • Several categories are renamed, for example “Authentication Failures” and “Security Logging and Alerting Failures”, which places more emphasis on acting on logs, not only collecting them.

Our practical advice: if a contract, policy or audit references the 2021 list, keep using it as the primary checklist and map the new 2025 categories onto your controls. Supply chain security and robust exception handling deserve attention regardless of which edition you cite. Always refer to the official OWASP project page for the authoritative wording.

Building security into your development lifecycle

A checklist is only useful if it is applied continuously. Security reviewed once before launch decays with every release. These are the practices we recommend embedding into everyday delivery:

  1. Design: include threat modelling and abuse cases in architecture and backlog refinement.
  2. Develop: follow framework conventions, use secure defaults, and refer developers to the OWASP Cheat Sheet Series for specific topics.
  3. Review: add security items to your pull request template, particularly any raw SQL, raw output, authorisation changes or new dependencies.
  4. Test: combine positive tests (authorised users can do their job) with negative tests (unauthorised users cannot). Our article on positive and negative testing explains why both matter.
  5. Automate: run static analysis, dependency scanning and secret scanning on every pull request, and dynamic scanning against a staging environment.
  6. Deploy and monitor: use hardened, reproducible infrastructure, then watch logs and alerts in production.
  7. Revisit: commission independent penetration testing for high-risk systems and after major changes.

Precision in software development includes precision in security. Attention to detail is what separates an application that merely works from one that can be trusted with your customers’ data.

How Adriel Corp can help

Security is built into how we work, from technology selection in the Conceptual Phase and architecture in the Structuring Phase to the positive and negative tests our QA team runs before anything is deployed. If you have an existing application and are not sure how it measures up against the OWASP Top 10, our Code Audit & Refactoring Sprint is designed to identify weaknesses such as outdated dependencies, missing access checks and risky code patterns, and then fix the most important ones.

Whether you need a review of a legacy platform or a new web application designed securely from day one, our team would be glad to help.

Let’s Talk

Frequently asked questions

What is the OWASP Top 10?

It is an awareness document published by the Open Worldwide Application Security Project that ranks the most critical security risk categories for web applications. It is based on contributed vulnerability data and a community survey, and is updated every few years.

Is complying with the OWASP Top 10 enough to make an application secure?

No. The Top 10 covers the most common and impactful risk categories, not every possible weakness. For a verifiable standard, use the OWASP Application Security Verification Standard (ASVS) alongside it.

Should we use the 2021 or 2025 edition?

Both remain useful. The 2025 edition reflects newer data, including software supply chain risk, but most of the 2021 categories carry over. If your contracts or audits reference the 2021 list, map your controls to both.

How does the OWASP Top 10 relate to POPIA?

POPIA requires responsible parties to take appropriate, reasonable technical and organisational measures to secure personal information. Addressing the OWASP Top 10 is a practical way to demonstrate reasonable technical measures for web applications.

How often should a web application be security tested?

Automated checks such as dependency scanning and static analysis should run on every build. Deeper manual reviews or penetration tests are sensible before major releases, after significant architectural changes and at least periodically for systems handling sensitive data.

Keep In Touch

Feel free to contact us for any project idea or collaboration

Let's Talk View packages