Vet’s checks map to specific OWASP ASVS (Application Security Verification Standard) control IDs. This document explains what ASVS is, how it’s structured, and which controls vet covers.
What is ASVS?
The OWASP Application Security Verification Standard is a framework of security requirements for designing, developing, and testing web applications. It defines ~280 controls organized into 14 categories, each specifying a testable security property.
ASVS is not a tool or a scanner. It’s a checklist. Tools like vet automate the testable subset of that checklist.
Verification levels
ASVS defines three levels of verification depth:
| Level | Target | Effort |
|---|---|---|
| Level 1 | All applications. Low assurance. Automated testing can cover most controls. | Low |
| Level 2 | Applications handling sensitive data. Most controls require testing against a running application. | Medium |
| Level 3 | High-value applications (banking, healthcare, critical infrastructure). Requires code review and architecture analysis. | High |
CASA Tier 2 maps to ASVS Level 2. Vet targets the automatable subset of Level 2 controls.
ASVS category structure
ASVS organizes controls by category prefix:
| Prefix | Category | Example |
|---|---|---|
| V1 | Architecture, Design and Threat Modeling | V1.1.1 |
| V2 | Authentication | V2.1.1 |
| V3 | Session Management | V3.1.1 |
| V4 | Access Control | V4.1.1 |
| V5 | Validation, Sanitization and Encoding | V5.1.1 |
| V6 | Stored Cryptography | V6.1.1 |
| V7 | Error Handling and Logging | V7.1.1 |
| V8 | Data Protection | V8.1.1 |
| V9 | Communication | V9.1.1 |
| V10 | Malicious Code | V10.1.1 |
| V11 | Business Logic | V11.1.1 |
| V12 | Files and Resources | V12.1.1 |
| V13 | API and Web Service | V13.1.1 |
| V14 | Configuration | V14.1.1 |
Not all categories are automatable. V1 (architecture) and V11 (business logic) require human judgment. Vet focuses on the categories that can be tested by sending HTTP requests and inspecting responses.
How to read vet’s control IDs
Every check in vet’s output has an id field that maps to an ASVS control:
V9.1.1
│ │ │
│ │ └─ Specific requirement (1st check in subcategory)
│ └─── Subcategory (Security Headers)
└───── Category (V9 = Communication)
Vet uses its own numbering within each subcategory to keep IDs stable across versions. The mapping is consistent but not always 1:1 with the ASVS spec numbering — vet groups some checks differently for practical testing reasons.
Which ASVS categories vet covers
V5 — Validation, Sanitization and Encoding
Vet tests input validation by sending attack payloads and malformed data to every discovered endpoint.
| Vet ID | What it tests |
|---|---|
| V5.1.1 | Request size limits (1MB payload) |
| V5.1.2 | Malformed JSON handling (parse errors → 400, not 500) |
| V5.1.3 | Missing required fields (empty body → 4xx, not 5xx) |
| V5.1.4 | Wrong field types (string-as-number → 4xx, not 5xx) |
| V5.3.3 | Reflected XSS (payload echoed unescaped in HTML) |
| V5.3.4 | SQL injection (SQL error patterns in response to SQLi payloads) |
| V5.3.8 | Path traversal (filesystem content in response to ../../ payloads) |
| V5.3.10 | Null byte injection (null bytes passed through in responses) |
What vet can detect: Error-based SQL injection, reflected XSS, basic path traversal, crash-inducing malformed input.
What vet can’t detect: Blind SQL injection, stored XSS, DOM-based XSS, second-order injection, business logic bypass through input manipulation.
V7 — Error Handling and Logging
Vet checks that error responses don’t leak internal information.
| Vet ID | What it tests |
|---|---|
| V7.4.1 | No stack traces (Node/Python/Java patterns) |
| V7.4.2 | No framework version strings (Express/, PHP/, nginx/) |
| V7.4.3 | No internal filesystem paths (/home/, /var/, C:\) |
| V7.4.4 | No database error strings or leaked SQL |
| V7.4.5 | No user-enumeration in auth errors (“user not found”, etc.) |
| V7.4.6 | 5xx responses are short and generic (no exception class names) |
Vet triggers errors by sending: path traversal in query params, malformed JSON, non-existent paths, path traversal in URL, and invalid bearer tokens.
V8 — Data Protection (planned)
Will test that tokens don’t appear in redirect URLs, error messages, or GET parameters.
V9 — Communication
The largest category in vet. Covers security headers, HTTP methods, TLS, and CORS.
V9.1.x — Security Headers:
| Vet ID | What it tests |
|---|---|
| V9.1.1 | HSTS with max-age ≥ 31536000 |
| V9.1.2 | X-Content-Type-Options: nosniff |
| V9.1.3 | X-Frame-Options or CSP frame-ancestors |
| V9.1.4 | Content-Security-Policy present, no unsafe-eval/unsafe-inline |
| V9.1.5 | Referrer-Policy (strict-origin-when-cross-origin or stricter) |
| V9.1.6 | Permissions-Policy restricts camera, microphone, geolocation |
| V9.1.7 | No Server version disclosure, no X-Powered-By |
| V9.1.8 | Cache-Control: no-store on auth endpoints |
V9.2.x — HTTP Method Enforcement:
| Vet ID | What it tests |
|---|---|
| V9.2.1 | TRACE blocked (405) |
| V9.2.2 | TRACK blocked (405 or non-echo 2xx) |
| V9.2.3 | PROPFIND blocked (405 or non-2xx) |
| V9.2.4 | OPTIONS returns proper CORS preflight or 405 |
V9.3.x — TLS/SSL:
| Vet ID | What it tests |
|---|---|
| V9.3.1 | Target uses HTTPS |
| V9.3.2 | TLS certificate valid (handshake succeeds) |
| V9.3.3 | HSTS header on HTTPS root |
| V9.3.4 | No mixed content (http:// in src/href/action) |
| V9.3.5 | HTTP redirects to HTTPS (or port 80 closed) |
| V9.3.6 | TLS 1.0 rejected (via openssl s_client) |
| V9.3.7 | TLS 1.1 rejected (via openssl s_client) |
V9.4.x — CORS:
| Vet ID | What it tests |
|---|---|
| V9.4.1 | Evil origin (https://evil.com) not reflected with credentials |
| V9.4.2 | Null origin not allowed |
| V9.4.3 | Wildcard (*) not combined with credentials |
| V9.4.4 | Preflight doesn’t allow dangerous methods from evil origin |
| V9.4.5 | Subdomain suffix origin (example.com.evil.com) not reflected |
V10 — Malicious Code / Webhook Security (planned)
Will test webhook signature validation: missing signature rejected, invalid signature rejected, replayed timestamp rejected.
V13 — API and Web Service / Rate Limiting (planned)
Will test that rate limits are enforced and return structured 429 responses.
V2 — Authentication / OAuth (planned)
Will test OAuth-specific flows: state replay, code replay, redirect_uri enforcement, PKCE, missing client_secret.
Coverage summary
| Category | Status | Checks |
|---|---|---|
| V5 — Input Validation | Implemented | 8 checks per endpoint |
| V7 — Error Handling | Implemented | 6 checks per endpoint |
| V9.1 — Security Headers | Implemented | 8 checks per endpoint |
| V9.2 — HTTP Methods | Implemented | 4 checks per endpoint |
| V9.3 — TLS/SSL | Implemented | 7 checks |
| V9.4 — CORS | Implemented | 5 checks per endpoint |
| V2 — OAuth Authentication | 🚧 Planned | Requires —client-id/—client-secret |
| V8 — Data Protection | 🚧 Planned | Token exposure checks |
| V10 — Webhook Security | 🚧 Planned | Signature validation checks |
| V13 — Rate Limiting | 🚧 Planned | 429 enforcement checks |
Total implemented: 38 unique check types, each run per discovered endpoint. A scan of an app with 10 endpoints produces ~300+ individual checks.
What ASVS doesn’t cover
ASVS focuses on application-level security. It does not cover:
- Infrastructure security (firewall rules, network segmentation)
- Physical security
- Social engineering
- Supply chain attacks (dependency vulnerabilities)
- Privacy regulations (GDPR, CCPA)
These are out of scope for both ASVS and vet.