All articles

OWASP Top 10: Web Application Security Risks Explained

The ten risk categories in the 2025 edition of the OWASP Top 10, what each looks like in a real business application, how to prevent it in Laravel, Django, or Node.js projects, and how to build these checks into the development process.

Security|Published |10 min read
A glowing circuit board pattern in teal light

The OWASP Top 10 is a list of the most important security risks in web applications, built from data on real vulnerabilities and a survey of security practitioners. Clients, auditors, and penetration testers often use it as a checklist, so development teams are regularly asked whether their application is "OWASP compliant". The list is better used as a map of where applications usually go wrong. This guide goes through the 2025 edition with examples of how each risk shows up in the business applications we build and review.

The 2025 List at a Glance

CategoryWhat it looks likeMain prevention
A01 Broken Access ControlChanging an ID in the URL shows another customer's invoice, or a normal user can call an admin endpointCheck ownership and role on the server for every request, deny by default
A02 Security MisconfigurationDebug mode on in production, default passwords, an open storage bucket, or a database port open to the internetHardened configuration kept in code and reviewed, with separate settings per environment
A03 Software Supply Chain FailuresAn outdated library with a known vulnerability, or a compromised package pulled into the buildLock files, dependency scanning, and a routine for updates
A04 Cryptographic FailuresPasswords stored with MD5, sensitive data sent over HTTP, or encryption keys committed to GitFramework password hashing, HTTPS everywhere, keys in a secrets manager
A05 InjectionSQL built by joining strings with user input, or user text rendered as HTMLParameterized queries and the ORM, output escaping by the template engine
A06 Insecure DesignA voucher that can be redeemed many times, or an OTP with no attempt limitThreat modelling of business flows and limits designed in from the start
A07 Authentication FailuresNo limit on login attempts, weak password reset, or sessions that never expireRate limits, multi-factor authentication for admins, secure session handling
A08 Software or Data Integrity FailuresAccepting a payment webhook without checking its signature, or deploying unsigned buildsVerify signatures, protect the CI/CD pipeline, avoid unsafe deserialization
A09 Security Logging and Alerting FailuresA breach found months later because failed logins and permission errors were never loggedLog security events centrally and alert on unusual patterns
A10 Mishandling of Exceptional ConditionsAn error that leaks a stack trace, or a failure that leaves a transaction half done and the user with accessFail closed, use transactions, and return generic error messages

Compared with the 2021 edition, server-side request forgery (SSRF) is now part of broken access control, supply chain risks have their own category, and error handling is new at A10. The first category has stayed at the top for years, and it is also the one automated scanners find least reliably.

Broken Access Control Deserves Most of Your Time

Frameworks protect against injection and cross-site scripting by default when you use them as intended. Access control is different, because only your code knows that invoice 1042 belongs to company A and that a branch manager may approve refunds up to a certain amount. Every endpoint that reads or changes data needs a check on the server, and hiding a button in the interface is not that check. In Laravel this means Policies, in Django object-level permissions in Django REST Framework, and in Node.js a shared authorization layer that every route goes through.

  • Load records through the current user or tenant, for example $request->user()->orders()->findOrFail($id), so another tenant's ID simply returns 404.
  • Write automated tests that log in as user A and request user B's data for every important endpoint.
  • Check file downloads and exports too. They are often added later and skip the normal checks.
  • Block requests from the server to internal addresses and cloud metadata endpoints when the application fetches URLs supplied by users.

Configuration and Dependencies

Misconfiguration and outdated components cause many of the incidents we see on servers that were never attacked in any clever way. Keep production settings in code or in a reviewed template, turn off debug output, remove default accounts, and make storage buckets private by default. Run composer audit, npm audit, or pip-audit in CI, enable Dependabot or Renovate, and schedule a regular slot for updates so they do not pile up until a major upgrade becomes frightening.

Design Flaws That No Scanner Finds

Insecure design is about business rules. A promotion that can be applied twice by sending two requests at the same time, a transfer that does not check the balance inside the same database transaction, or an OTP that can be guessed because there is no attempt limit. These need a short threat modelling session when a feature is designed: ask how a dishonest user would abuse this flow, then add limits, locks, and checks before the code is written.

Building Security Into the Process

  1. 1Add a short security checklist based on the Top 10 to the pull request template and to the definition of done.
  2. 2Run static analysis such as SonarQube or Semgrep and dependency scanning on every pull request.
  3. 3Write access control tests for every endpoint that touches customer or financial data.
  4. 4Scan the running application with a dynamic scanner such as OWASP ZAP or Qualys before major releases.
  5. 5Log logins, permission failures, and admin actions to a central place and set alerts on unusual spikes.
  6. 6Have an external penetration test at least once a year or before launching a system that handles payments or personal data.

For applications that process personal data of Indonesian users, these practices also support the security obligations in the Personal Data Protection Law (UU PDP). A record of scans, fixes, and tests is useful evidence when a client or auditor asks how the application is protected.

Key takeaways

  • Use the OWASP Top 10 as a map of where applications usually fail.
  • Spend the most effort on access control and test it with real users and real IDs.
  • Keep configuration reviewed in code and update dependencies on a schedule.
  • Look for business logic abuse during design, because scanners cannot find it.
  • Automate static, dependency, and dynamic scans, and log security events centrally.

Related articles

More articles on software development, AI, cloud, and infrastructure.

A smartphone home screen full of app icons
Mobile Development|

How to Publish an App to Google Play and the App Store

What you need before submitting a mobile app: developer accounts for a person or a company, signing keys, store listings and privacy forms, the closed testing rule for new Play accounts, TestFlight, common App Store rejections, and staged releases.

A laptop showing a business dashboard next to a coffee mug
Software Development|

Custom Software vs SaaS: How to Decide for Your Business

When an off-the-shelf SaaS product is the better buy, when custom software pays for itself, how to compare costs over several years, the hybrid route of SaaS plus custom integrations, and the questions to ask before signing either.

Looking for a software development partner?

Tell us about your project, what you need to build, and the challenges you are facing. We can discuss the technical approach, scope, timeline, and estimated cost.

Start a conversation