All posts
·7 min read·Baseframe

OWASP ASVS Level 2: what it actually means for a business app

ASVS Level 2 covers 14 chapters and roughly 200 security requirements. Here's what those requirements mean in practice for a business application handling financial data.

securityowasptechnical

Most security marketing is vague by design. "Enterprise-grade security" means nothing. "Bank-level encryption" means nothing. "SOC 2 compliant" means the company passed an audit last year — it says nothing about the quality of the actual software.

We build to OWASP ASVS Level 2. That's a specific claim with specific meaning, and I want to explain what it actually means for a business application that handles customer financial data.


What ASVS is

The Application Security Verification Standard is published by the Open Web Application Security Project (OWASP), the same organization behind the OWASP Top 10 you've probably heard of. ASVS is more detailed — it's a framework for testing and verifying the security of web applications, organized into 14 chapters covering different attack surfaces.

The three levels are:

Level 1 — Basic security hygiene. The minimum for any application exposed to the internet. Covers the most obvious vulnerabilities from the OWASP Top 10.

Level 2 — Standard for applications containing sensitive data. The majority of the ~200 requirements apply at this level. This is where business applications handling financial data, health data, or personal information should operate.

Level 3 — For critical infrastructure. Applications where a security failure could result in significant harm to a large number of people — healthcare systems, critical financial infrastructure, government applications. The requirements at this level go significantly deeper into cryptographic implementations and physical security.

Level 2 is the appropriate target for a business operations platform. It's demanding — 200 requirements is a lot to verify — but it's not theoretical. It's achievable by a focused development team that builds security in from the start rather than bolting it on at the end.


What the 14 chapters actually cover

Let me go through each chapter and what it means in practice.

V1: Architecture, Design, and Threat Modeling — Before writing code, document your threat model. Know where sensitive data flows, what the trust boundaries are, and what an attacker would target. This sounds obvious. Most development skips it.

V2: Authentication — Passwords must be hashed with bcrypt, scrypt, or Argon2 (not MD5, not SHA-1). Account lockout after repeated failures. Re-authentication for sensitive operations. We use Microsoft Entra ID for internal auth, which handles most of this at the identity provider level.

V3: Session Management — Session tokens must be cryptographically random, sufficiently long (at least 64 bits), and invalidated properly on logout. Session cookies must have the HttpOnly, Secure, and SameSite flags set. Session fixation attacks must be prevented by issuing a new token after authentication.

V4: Access Control — Every endpoint must verify that the authenticated user is authorized to perform the requested action. This sounds obvious. "Broken Access Control" has been the number-one risk in the OWASP Top 10 since 2021 because developers forget to check authorization deep in the call stack. We enforce authorization at every server action and route handler, not just at the route level.

V5: Validation, Sanitization, and Encoding — All user input must be validated against an allowlist before processing. Output must be encoded to prevent cross-site scripting. SQL queries must use parameterized statements — no string concatenation. We use Zod for input validation on every server action and API endpoint.

V6: Stored Cryptography — Sensitive data at rest must be encrypted with approved algorithms (AES-256 or equivalent). Cryptographic keys must be stored separately from the data they protect. Keys must be rotatable without re-encrypting all data. We rely on managed PostgreSQL encryption at rest for the database layer.

V7: Error Handling and Logging — Errors shown to users must not include stack traces, internal paths, or database queries. Application errors must be logged with sufficient context to investigate but without logging sensitive data (card numbers, passwords, SSNs). We filter sensitive fields from all log output.

V8: Data Protection — Sensitive data must be identifiable in the data model (so it can be protected appropriately). Data sent to the browser must include only what the user is authorized to see — not entire records with sensitive fields filtered in the UI. Server-side filtering is the rule.

V9: Communication — All communication must use TLS 1.2 or higher. TLS 1.0 and 1.1 must be disabled. HSTS headers must be set. Certificate validation must be enforced. We run TLS 1.3 everywhere.

V10: Malicious Code — No backdoors, no undocumented data exfiltration, no hidden functionality. The code must do what it says it does. Dependencies with known malicious code must not be used. We audit dependencies via Dependabot and keep them current.

V11: Business Logic — Security controls must be applied to business logic, not just authentication. Rate limiting on payment operations. Maximum transaction amounts. Preventing replay attacks on time-sensitive operations. This chapter is highly application-specific — what counts as "correct" business logic varies by domain.

V12: Files and Resources — File uploads must be validated (content type, not just extension). Files must not be stored in web-accessible directories. File processing must not be vulnerable to path traversal. We validate file uploads server-side and store them in object storage outside the document root.

V13: API and Web Service — API endpoints must enforce the same authentication and authorization as UI endpoints. Rate limiting must be applied. Input validation applies to all API inputs, not just UI form submissions. GraphQL endpoints require additional protections (query depth limiting, introspection disabled in production).

V14: Configuration — Applications must not run with more permissions than necessary. Debug modes must be disabled in production. Default credentials must not exist. Security headers (CSP, X-Frame-Options, etc.) must be configured. We use Next.js middleware to set security headers on all responses.


How we verify compliance

"We build to ASVS Level 2" is easy to claim. Verifying it is harder.

Our approach:

During development, we use the ASVS checklist as a code review guide. When a developer submits a pull request that touches authentication, the reviewer checks it against the V2 requirements. When a PR touches input handling, V5 gets reviewed.

Quarterly, we run SAST tooling and Dependabot scans. We can't merge PRs with critical or high-severity dependency alerts outstanding.

Annually, we commission external penetration testing from a CREST-accredited firm. They have access to the codebase and spend several days actively trying to break it. The findings from the pen test feed directly into the next development cycle.

The annual pen test is the most important part. Automated tools catch known vulnerability patterns. A skilled human tester finds the things that don't match patterns — the business logic flaws, the access control gaps that only appear when you understand how the application actually works.


What ASVS doesn't cover

ASVS is an application security standard. It doesn't cover:

  • Physical security of the servers running the application (that's the cloud provider's responsibility)
  • Operational security of the people running the application (separate topic)
  • Incident response procedures
  • Business continuity and disaster recovery

For a business operations platform, these are also important. We address them — but they're outside the scope of what ASVS verifies, and I don't want to claim ASVS coverage for things it doesn't cover.


Why this matters for a business application

If you're running a wholesale distribution operation and a breach exposes your customer list, your invoice history, and your payment processing credentials, the damage is real and specific: customer trust destroyed, potential liability, regulatory scrutiny.

Most small business software is built at Level 0 — the developer thought about SQL injection and XSS but didn't work through 200 requirements systematically. That's not a criticism; it's the default when you're moving fast and security feels abstract.

When we say we build to OWASP ASVS Level 2, we mean we went through 200 specific requirements and verified each one. Not all of them apply to every application — some are for specific technology stacks or features we don't use. But we checked.

That's the standard we hold ourselves to. We think it's the right one for software handling real financial data.