Skip to content

Securing a Web App Against the OWASP Top 10: A Developer's Checklist

Security7 min readBy the Nexzem team

A practical checklist developers can apply to the OWASP Top 10:2025: access control and SSRF, misconfiguration, supply chain, injection, authentication, logging and exceptional conditions.

In this article
  1. 01How to use the OWASP Top 10
  2. 02Broken access control, including SSRF
  3. 03Security misconfiguration
  4. 04Software supply chain failures and integrity
  5. 05Cryptography and secrets
  6. 06Injection and cross-site scripting
  7. 07Authentication failures and sessions
  8. 08Insecure design and exceptional conditions
  9. 09File uploads
  10. 10APIs and mobile backends
  11. 11Logging, alerting and testing

How to use the OWASP Top 10

The OWASP Top 10 is a ranked list of the most critical web application security risks, based on data from real applications and community input. OWASP revises it every few years. The current 2025 edition keeps broken access control at the top and folds server-side request forgery (SSRF) into it, makes software supply chain failures a category of its own and adds a new category for mishandling of exceptional conditions.

It is an awareness document, not a complete standard. Use it to make sure your team covers the big risks, and use the OWASP Application Security Verification Standard (ASVS) when you need a detailed list of requirements. The checklist below groups practical controls by risk area.

Broken access control, including SSRF

Broken access control is the most common serious flaw: users reading or changing data that is not theirs. The classic example is an insecure direct object reference, where changing /invoices/1042 to /invoices/1043 shows someone else's invoice.

  • Deny by default and check permissions on the server for every request, never only in the UI
  • Check object ownership, not just the user's role, whenever an ID comes from the client
  • Centralize authorization logic instead of repeating it in each route
  • Restrict CORS to known origins and never reflect arbitrary origins with credentials
  • Test with two accounts in automated tests: user A must not access user B's resources
  • For cookie-based sessions, protect state-changing requests against cross-site request forgery with SameSite cookies and anti-CSRF tokens
  • For server-side request forgery, which the 2025 edition groups under broken access control, validate and allowlist outbound URLs and block internal ranges, including the cloud metadata address 169.254.169.254
  • On AWS, require IMDSv2 for instance metadata

Security misconfiguration

Many breaches need no clever exploit, just a setting left open. Disable debug modes and verbose error pages in production, remove default accounts and sample apps, send security headers such as Content-Security-Policy, X-Content-Type-Options and a frame-ancestors policy, and make sure cloud storage buckets are private unless deliberately public. Grant cloud permissions on a least-privilege basis and review them regularly.

Automate these checks where you can. Infrastructure as code scanners such as Checkov, container image scanners and cloud security posture tools catch many misconfigurations before deployment, and a simple security header test in CI stops headers from silently disappearing after a framework upgrade.

Software supply chain failures and integrity

Your application is mostly other people's code. Commit lockfiles, scan dependencies with npm audit, Dependabot, Renovate or a similar tool and review new dependencies before adding them. Pin CI actions and build images to specific versions, generate a software bill of materials for releases and sign build artifacts where your platform supports it. Verify signatures on incoming webhooks and avoid deserializing untrusted data into objects.

Cryptography and secrets

Use TLS for all traffic, including between internal services where practical, and enable HSTS. Encrypt sensitive data at rest using your cloud provider's managed keys, and never invent your own cryptography. Keep secrets in a secret manager rather than in code, environment files committed to Git or container images, and rotate them when people leave or a leak is suspected. Our JWT decoder is handy for inspecting tokens while testing these flows.

Injection and cross-site scripting

Injection happens when untrusted input is interpreted as code or a query. Use parameterized queries or an ORM's query builder for every database call, and be especially careful with raw queries built by string concatenation, which is how SQL injection still happens in modern stacks. Never pass user input to shell commands.

For cross-site scripting, rely on your framework's automatic output encoding and avoid bypasses like dangerouslySetInnerHTML or v-html unless the content is sanitized with a library such as DOMPurify. Add a Content Security Policy that blocks inline scripts as a second line of defense.

Authentication failures and sessions

Authentication failures let attackers take over accounts. These controls cover most of the risk:

  • Offer multi-factor authentication, and require it for administrators
  • Hash passwords with a slow algorithm such as Argon2id or bcrypt, never a fast hash
  • Rate limit login, password reset and OTP endpoints, and avoid revealing whether an account exists
  • Set session cookies with HttpOnly, Secure and an appropriate SameSite value, and issue a new session ID on login
  • For JWTs, fix the accepted algorithm, verify the signature and check expiry, issuer and audience
  • Expire idle sessions and let users see and revoke their active sessions from account settings

Insecure design and exceptional conditions

Some flaws are designed in. Spend an hour threat modeling each major feature: what could a malicious user do with it? Add rate limits to business flows such as coupon redemption, and confirm sensitive actions.

The 2025 edition also adds mishandling of exceptional conditions as its own category: errors, timeouts and unexpected input that leave an application in an unsafe state.

  • Fail closed: if an authorization check errors, deny the request
  • Roll back partial transactions when a step fails, so an error cannot leave data half-written
  • Show users generic error messages and log the details server-side

File uploads

File upload features combine several risks at once. Treat every uploaded file as hostile:

  • Check file type by content, not by extension or the client-supplied content type
  • Enforce size limits at the proxy and in the application
  • Store files in object storage with random names, never in a directory the web server executes
  • Serve user files from a separate domain, with Content-Disposition set to attachment where appropriate
  • Strip metadata from images and scan files for malware where the risk warrants it

APIs and mobile backends

Attackers call your API directly, without your app or your UI checks, so every endpoint needs the same authorization as any page. Watch for mass assignment, where an update endpoint accepts any field in the request body and a user sets role or is_admin on their own account; bind only explicitly allowed fields. Return only the fields the client needs rather than whole database records. An application security review should look at exactly these API-level issues.

Logging, alerting and testing

Log authentication events, access control failures and high-value transactions with enough context to investigate, but never log passwords, tokens or full card numbers. Send logs to a central system and alert on patterns such as bursts of failed logins; the 2025 edition renames this category Security Logging and Alerting Failures, because logs nobody is alerted on do little. Finally, test: add security checks to code review, run dependency and static analysis in CI and commission independent testing before major releases. Nexzem's VAPT services cover this kind of assessment.

Planning something similar?

Get a straight answer on scope, cost and timeline.

Talk to the team

Tell us what you're building.

A solutions consultant replies within one business day with next steps, a rough estimate and a suggested team.