Skip to content

OWASP ASVS 5.0.0 complete control ledger ​

Assessment date: 2026-08-18; local MFA posture updated 2026-10-09. Every Level 1–3 requirement is assessed. Password-only deployments do not meet the Level 2 multi-factor requirement. Baseline: OWASP Application Security Verification Standard 5.0.0 (May 2025), 345 requirements.

This ledger is an evidence-based source/configuration review, not an OWASP certification. It uses:

  • Pass — implemented or deliberately avoided, with repository evidence and tests where practical;
  • Partial — meaningful controls exist, but a clause, deployment proof or higher-assurance aspect is incomplete;
  • Gap — applicable requirement is not implemented;
  • N/A — the governed technology/function does not exist in CapacityLens.

An inherited library/framework control is only marked Pass where the application constrains its use and the behavior is covered by configuration/tests or the maintained library contract. External TLS, disks, collectors, secret stores and identity-provider policy cannot become Pass merely because an environment acknowledgement is set; those stay Partial where deployment evidence is required. Requirement descriptions are not reproduced here; use the official ASVS release alongside these IDs.

Original 2026-08-18 totals: 200 Pass, 48 Partial, 7 Gap and 90 N/A = 345. Following the 2026-10-09 local MFA removal and this control review, the amended rows total 185 Pass, 54 Partial, 8 Gap and 98 N/A = 345. These are not a score or certification percentage.

V1 Encoding and sanitization ​

SectionEvidence summaryPassPartialGapN/A
V1.1 ArchitectureFastify parses once; shared sanitisation precedes domain use; React/JSON perform contextual output encodingV1.1.2V1.1.1——
V1.2 Injection preventionReact text nodes, encoded URL components, structured JSON, parameterized SQLite, fixed/bounded regexV1.2.1, V1.2.2, V1.2.3, V1.2.4, V1.2.9——V1.2.5, V1.2.6, V1.2.7, V1.2.8, V1.2.10
V1.3 SanitizationNo eval; context-specific codecs/lengths; operator-only HTTPS URL allow-list; bounded fixed regex; account email uses structured SMTP transport fieldsV1.3.2, V1.3.3, V1.3.6, V1.3.12V1.3.11—V1.3.1, V1.3.4, V1.3.5, V1.3.7, V1.3.8, V1.3.9, V1.3.10
V1.4 Memory/numeric safetyMemory-safe JS/TS runtime, bounded integer parsers and explicit shutdown/resource releaseV1.4.1, V1.4.2, V1.4.3———
V1.5 Safe parsingTyped JSON/object allow-listing; Node URL parser; no XMLV1.5.2V1.5.3—V1.5.1

V2 Validation and business logic ​

SectionEvidence summaryPassPartialGapN/A
V2.1 DocumentationAGENTS.md, DEFENSIVE-CODING.md, domain invariants and control inventory define shape/context/limitsV2.1.1, V2.1.2, V2.1.3———
V2.2 EnforcementServer/domain validation is authoritative; related entity/account/date/activity rules checkedV2.2.1, V2.2.2, V2.2.3———
V2.3 Flows/transactionsSetup/invite/link/cutover order, SQLite transactions, sync provenance, stale-import checks and atomic replacementV2.3.1, V2.3.2, V2.3.3——V2.3.4, V2.3.5
V2.4 Anti-automationAPI/health throttling and request/import/batch boundsV2.4.1——V2.4.2

V3 Web frontend security ​

SectionEvidence summaryPassPartialGapN/A
V3.1 Browser feature modelEvergreen-browser cross-browser suite and security headers; no full incompatible-browser block—V3.1.1——
V3.2 Rendering contextJSON MIME/nosniff/CORP plus React text rendering and TypeScript module scopeV3.2.1, V3.2.2, V3.2.3———
V3.3 CookiesHTTPS emits Secure, Path=/, domain-free __Host- cookies; HTTP loopback uses development names; SameSite=Lax, HttpOnly and bounded cookiesV3.3.1, V3.3.2, V3.3.3, V3.3.4, V3.3.5———
V3.4 Browser headersTwo-year host-only HSTS, exact CORS, CSP with inline style elements forbidden, nosniff, no-referrer, frame denial and COEP/COOP/CORP; bounded CSP reports project into the security streamV3.4.1, V3.4.2, V3.4.4, V3.4.5, V3.4.6, V3.4.7, V3.4.8V3.4.3——
V3.5 Cross-origin controlsUnsafe Origin/Fetch-Metadata rejection, correct methods, no JSONP/script data, same-origin CORPV3.5.1, V3.5.2, V3.5.3, V3.5.6, V3.5.7, V3.5.8——V3.5.4, V3.5.5
V3.6 External assetsRuntime JS/CSS/fonts are self-hosted; no CDN runtime dependencyV3.6.1———
V3.7 Client behaviorSupported web platform only; external provider navigation is explicit/user-selected; preload/incompatible-browser behavior is deployment-dependentV3.7.1, V3.7.2, V3.7.3V3.7.4, V3.7.5——

V4 API and web service ​

SectionEvidence summaryPassPartialGapN/A
V4.1 HTTP useCorrect content types and explicit methods; packaged TLS proxy behavior needs deployment proofV4.1.1, V4.1.4V4.1.2, V4.1.3—V4.1.5
V4.2 Message framingCurrent nginx/Fastify/Node framing; auth proxy strips length/transfer headers; outbound URI/header compatibility needs evidence—V4.2.1, V4.2.2, V4.2.3, V4.2.4, V4.2.5——
V4.3 GraphQLNo GraphQL endpoint———V4.3.1, V4.3.2
V4.4 WebSocketNo WebSocket endpoint———V4.4.1, V4.4.2, V4.4.3, V4.4.4

V5 File handling ​

SectionEvidence summaryPassPartialGapN/A
V5.1 DocumentationJSON import is the sole file-like input; type, 5 MiB and record limits documented/testedV5.1.1———
V5.2 Uploaded contentJSON content parsed/validated with body/record caps; extension/content agreement is not enforcedV5.2.1V5.2.2—V5.2.3, V5.2.4, V5.2.5, V5.2.6
V5.3 Storage/pathServer data/audit/backup paths are operator configuration, not user filenames; no public uploaded code/archiveV5.3.2——V5.3.1, V5.3.3
V5.4 DownloadsExport is a browser Blob with a fixed anchor download name, not an HTTP attachment responseV5.4.2——V5.4.1, V5.4.3

V6 Authentication ​

SectionEvidence summaryPassPartialGapN/A
V6.1 DocumentationAuth pathways, throttling/lockout, context words, password and company-provider strength documentedV6.1.1, V6.1.2, V6.1.3———
V6.2 Passwords15–128, change/current-password flow, HIBP by default, no composition rule, paste/managers, exact bytes, no periodic expiry; a guaranteed top-3000 policy-matching list is not provedV6.2.1, V6.2.2, V6.2.3, V6.2.5, V6.2.6, V6.2.7, V6.2.8, V6.2.9, V6.2.10, V6.2.11V6.2.4, V6.2.12——
V6.3 Authentication controlsAPI throttling, no default account, documented paths; failed-challenge indistinguishability across responses and timing remains unprovedV6.3.1, V6.3.2, V6.3.4, V6.3.6V6.3.8V6.3.3, V6.3.5, V6.3.7—
V6.4 RecoveryProduction setup avoids initial passwords; password reset revokes sessions; stopped-server sole-Owner recovery uses the same single-use flow and exact eligibility; local MFA recovery does not applyV6.4.1, V6.4.2, V6.4.3, V6.4.6——V6.4.4, V6.4.5
V6.5 Factor propertiesNo local authenticator, TOTP enrolment or recovery-code flow; Google and Microsoft own any factor policy———V6.5.1, V6.5.2, V6.5.3, V6.5.4, V6.5.5, V6.5.6, V6.5.7, V6.5.8
V6.6 Out-of-band/PSTNNo SMS, phone, email-code or push factor———V6.6.1, V6.6.2, V6.6.3, V6.6.4
V6.7 Cryptographic authenticatorNo hardware cryptographic authenticator———V6.7.1, V6.7.2
V6.8 Federated identityProvider+subject identity, asymmetric signature validation, verified-email admission and explicit linking; SSO MFA remains an operator assurance rather than claim-level enforcementV6.8.1, V6.8.2V6.8.4—V6.8.3

V7 Session management ​

SectionEvidence summaryPassPartialGapN/A
V7.1 DocumentationAbsolute/freshness/concurrency policy documented; provider session coordination remains experimentalV7.1.1, V7.1.2V7.1.3——
V7.2 Token creation/verificationBackend stateful CSPRNG reference sessions; new token on authenticationV7.2.1, V7.2.2, V7.2.3, V7.2.4———
V7.3 TimeoutsFixed 12-hour absolute limit, 30-minute server-enforced inactivity expiry and no sliding absolute refreshV7.3.1, V7.3.2———
V7.4 TerminationLogout/expiry/deletion/reset/revocation are immediate; self/admin controls and visible logoutV7.4.1, V7.4.2, V7.4.3, V7.4.4, V7.4.5———
V7.5 ReauthenticationCurrent password or provider sign-in and fresh privileged actions; session termination uses freshness rather than an always-new promptV7.5.1, V7.5.3V7.5.2——
V7.6 FederationSession creation is user-initiated; provider logout/lifetime coordination needs provider testingV7.6.2V7.6.1——

V8 Authorization ​

SectionEvidence summaryPassPartialGapN/A
V8.1 DocumentationFunction/data/field/action rules and only contextual control (session freshness) are documentedV8.1.1, V8.1.2, V8.1.3, V8.1.4———
V8.2 EnforcementCentral role/action, account/object/parent-reference and field rules; project-bound writes fail closed when the parent cannot be resolved in-tenant; no adaptive environment/device engineV8.2.1, V8.2.2, V8.2.3—V8.2.4—
V8.3 Trusted layer/immediacyServer-side DB membership on every operation; changes/revocations immediate; no privilege-bearing intermediaryV8.3.1, V8.3.2, V8.3.3———
V8.4 Multi-tenancy/adminIndependent cross-tenant enforcement; only specified sensitive actions require freshness; no local MFA gate or continuous device/risk assessmentV8.4.1V8.4.2——

V9 Self-contained tokens ​

SectionEvidence summaryPassPartialGapN/A
V9.1 IntegrityApplication sessions are stateful; configured OIDC assertions use maintained issuer/signature/algorithm/key validationV9.1.1, V9.1.2, V9.1.3———
V9.2 ClaimsProvider tokens are checked for validity, type and audience by the protocol library; CapacityLens is not a token issuerV9.2.1, V9.2.2, V9.2.3——V9.2.4

V10 OAuth and OIDC ​

SectionEvidence summaryPassPartialGapN/A
V10.1 Token/client bindingProvider tokens stay server-side and are encrypted at rest; maintained clients provide state/nonce/transaction bindingV10.1.1, V10.1.2———
V10.2 Client flowsLibrary state/PKCE/mix-up defenses; least default scopesV10.2.1, V10.2.2, V10.2.3———
V10.3 Resource serverCapacityLens does not accept OAuth access tokens as an API resource server———V10.3.1, V10.3.2, V10.3.3, V10.3.4, V10.3.5
V10.4 Authorization serverCapacityLens is not an OAuth authorization server———V10.4.1, V10.4.2, V10.4.3, V10.4.4, V10.4.5, V10.4.6, V10.4.7, V10.4.8, V10.4.9, V10.4.10, V10.4.11, V10.4.12, V10.4.13, V10.4.14, V10.4.15, V10.4.16
V10.5 OIDC relying partyMaintained nonce/subject/issuer/audience validation; no back-channel logoutV10.5.1, V10.5.2, V10.5.3, V10.5.4——V10.5.5
V10.6 OpenID ProviderCapacityLens is not an OpenID Provider———V10.6.1, V10.6.2
V10.7 ConsentCapacityLens is not an authorization server managing third-party grants———V10.7.1, V10.7.2, V10.7.3

V11 Cryptography ​

SectionEvidence summaryPassPartialGapN/A
V11.1 Inventory/lifecycleRepository crypto inventory plus a gate-enforced automated implementation-path discovery check; deployment key rotation/PQC migration remain operator/planning workV11.1.2, V11.1.3V11.1.1, V11.1.4——
V11.2 Design/implementationNode/Web Crypto/Better Auth, ≥128-bit primitives and fail-closed errors; versioned formats but legacy hashes and library timing remainV11.2.1, V11.2.3, V11.2.5V11.2.2, V11.2.4——
V11.3 Symmetric encryptionAuthenticated offline AES-256-GCM plus Better Auth provider-token encryption; no separate cipher+MAC constructionV11.3.1, V11.3.2, V11.3.3, V11.3.4——V11.3.5
V11.4 Hash/KDFSHA-256 token digests, versioned OWASP scrypt and appropriate derived lengths; SHA-1 only for non-verifier HIBP protocolV11.4.1, V11.4.2, V11.4.3, V11.4.4———
V11.5 RandomnessPlatform CSPRNG with ≥128-bit security for tokens/keys and OS heavy-demand behaviorV11.5.1, V11.5.2———
V11.6 Key generation/exchangePlatform-approved generation and TLS exchange primitivesV11.6.1, V11.6.2———
V11.7 In-use dataData minimisation/short-lived values exist; no full-memory encryption and necessary plaintext exists while processing—V11.7.2V11.7.1—

V12 Secure communication ​

SectionEvidence summaryPassPartialGapN/A
V12.1 TLS configurationPublic TLS/version/ciphers are proxy/operator evidence; no mTLS client; OCSP/ECH not supplied by app—V12.1.1, V12.1.2V12.1.4, V12.1.5V12.1.3
V12.2 Public servicesDocumentation mandates public TLS/trusted certificates, but source review cannot verify a deployed endpoint—V12.2.1, V12.2.2——
V12.3 Other connectionsOutbound HTTPS validates certificates; packaged nginx verifies a per-install CA/service identity over TLS 1.2/1.3, while same-host bare-metal HTTP is permitted; public monitoring/operator protocols are externalV12.3.2V12.3.1, V12.3.3—V12.3.4, V12.3.5

V13 Configuration ​

SectionEvidence summaryPassPartialGapN/A
V13.1 Communication/resourcesCommunication inventory defines socket/service/work maxima, queue/timeout/refusal behavior and recovery; deployment certificate/credential rotation remains operator-specificV13.1.1, V13.1.2V13.1.3, V13.1.4——
V13.2 Backend communicationUnprivileged components, no defaults, fixed/configured outbound endpoints; network egress and connection policy require deployment controlsV13.2.2, V13.2.3V13.2.4, V13.2.5, V13.2.6—V13.2.1
V13.3 Secret managementDocs require secret manager/least privilege/rotation; env delivery is supported, not a vault/HSM or enforced expiry—V13.3.1, V13.3.2, V13.3.4V13.3.3—
V13.4 Production exposure.dockerignore, production-only dependencies, no debug/reset, no listing/TRACE, intentional health, no detailed backend versions, exact static-file handlingV13.4.1, V13.4.2, V13.4.3, V13.4.4, V13.4.5, V13.4.6, V13.4.7———

V14 Data protection ​

SectionEvidence summaryPassPartialGapN/A
V14.1 ClassificationPrivacy/control inventories identify data classes and application/operator protectionsV14.1.1, V14.1.2———
V14.2 Server-side protectionAPI no-store, no trackers, projection/minimisation and 404 file behavior; link tokens, deployment storage and retention remain partialV14.2.2, V14.2.3, V14.2.5, V14.2.6V14.2.1, V14.2.4, V14.2.7—V14.2.8
V14.3 Browser dataAPI no-store; logout clears offline data, but no universal Clear-Site-Data; encrypted opt-in tenant snapshots still reside in IndexedDBV14.3.2V14.3.1, V14.3.3——

V15 Secure coding and architecture ​

SectionEvidence summaryPassPartialGapN/A
V15.1 Documentation/inventoryRemediation policy, SBOM/third parties, expensive/risky/dangerous function inventoryV15.1.1, V15.1.2, V15.1.3, V15.1.4, V15.1.5———
V15.2 Components/resourcesAudits/scans, bounded heavy paths, minimal production graph with leak assertion, lockfile-recorded patch, non-root read-only containersV15.2.1, V15.2.2, V15.2.3, V15.2.4, V15.2.5———
V15.3 Defensive implementationOutput projection, no-redirect outbound call, allowlisted fields, trusted proxy, strict TS/types/prototype/parameter handlingV15.3.1, V15.3.2, V15.3.3, V15.3.4, V15.3.5, V15.3.6, V15.3.7———
V15.4 ConcurrencySQLite atomic checks; import workers receive structured clones, use bounded FIFO slots/deadlines/cancellation, and recheck tenant state before commitV15.4.2, V15.4.4——V15.4.1, V15.4.3

V16 Security logging and error handling ​

SectionEvidence summaryPassPartialGapN/A
V16.1 InventoryLayer/event/format/destination/sensitivity inventory exists; actual access control and retention need operator evidence—V16.1.1——
V16.2 Log contentUTC ISO metadata, documented JSON streams and credential/body redaction; clock synchronization and deployed processor correlation need evidenceV16.2.1, V16.2.3, V16.2.5V16.2.2, V16.2.4——
V16.3 Security eventsAuth, bypass/control failures, queue saturation, SSO cutover/repair, operator recovery and unexpected errors logged; not every successful L3 decision is recordedV16.3.1, V16.3.3, V16.3.4V16.3.2——
V16.4 Log protectionJSON serialization prevents injection and local files have restrictive modes; external forwarding is optional and its ACL/immutability need operator evidenceV16.4.1V16.4.2, V16.4.3——
V16.5 Failure handlingGeneric responses, fail-closed external/control failures and transaction rollback; a process-wide last-resort handler records the local error plus a sanitized security event, drains, exits non-zero and relies on supervisor restart rather than continuing potentially corrupt stateV16.5.1, V16.5.2, V16.5.3V16.5.4——

V17 WebRTC ​

SectionEvidence summaryPassPartialGapN/A
V17.1 TURNNo WebRTC/TURN———V17.1.1, V17.1.2
V17.2 MediaNo DTLS/SRTP/media server or recording———V17.2.1, V17.2.2, V17.2.3, V17.2.4, V17.2.5, V17.2.6, V17.2.7, V17.2.8
V17.3 SignalingNo WebRTC signaling server———V17.3.1, V17.3.2

Input-boundary evidence update (2026-10-10) ​

The classifications above reflect the SMTP and local MFA applicability corrections as well as new evidence against the applicable ASVS 5.0.0 release and Input Validation Cheat Sheet.

ControlsEvidence and limitAssessment boundary
V1.1, V1.2, V1.3, V2.1–V2.2Shared NFC/whitespace normalization runs before 100-code-point name and 1,000-code-point note limits; strict ordinary-write validation rejects malformed supplied fields while import repair remains separate. React renders text as text and SQLite binds values.No rich-HTML or dynamic SQL sink was found in the reviewed paths. Valid punctuation remains allowed.
V1.4–V1.5, V4.1–V4.2Fastify's 5 MiB request cap precedes application JSON scanning; the scan rejects duplicate decoded keys, depth over 64, non-finite numbers, unsafe integers and nonzero numeric underflow, then Fastify's hardened parser owns syntax. Browser import rejects malformed UTF-8.V1.5.3 and V4.2 remain Partial. Provider/authentication protocol requests retain their framework-owned parser and are outside the custom scan; this review did not independently prove every provider payload rule.
V2.3–V2.4, V5.1–V5.2200,000 import records and 5,000 batch operations remain capped; strict batch rejection and server import replacement are atomic. Approved-domain input is capped at 50 raw entries and 16 KiB UTF-8 before IDNA.Imported legacy row repair or skipping remains deliberate and reported; a malformed whole file cannot replace stored data.
V8.1–V8.4Scope, relationship, lifecycle, repeat-series and confidential-field pins remain enforced by the server independently of form visibility.Blind writers may echo redacted or blank hidden fields; the stored confidential value is retained. Existing role and tenant tests cover these exceptions.
V16.2–V16.5Parser failures return an allowlisted 400 error; rejected values, passwords and setup secrets are not included in the response. Structured audit/security logging retains its existing redaction and failure policy.Deployment log retention and external collector controls remain Partial where shown above.

The control IDs and classifications in the main tables remain authoritative. The following Partial/Gap outcomes identify what evidence or separate capability would be needed; these are not claims that input validation alone completes another control.

Control IDs and current statusRemaining outcome and evidence owner
V1.1.1, V1.5.3 — PartialMaintainers must audit every parser and downstream encoding context, including provider-owned protocol bodies, against the maintained parser contracts; the application scan does not cover /api/auth/.
V1.3.11 — PartialAccount addresses are validated and handed to structured nodemailer fields. The review has not proved every user-controlled SMTP field and transport library behavior against header injection.
V4.1.2 — PartialThe packaged proxy redirects HTTP requests, but the requirement permits automatic redirects only for browser-facing endpoints. Operators and maintainers must show that API requests over HTTP are rejected and cannot hide cleartext client requests.
V4.1.3, V4.2.1–V4.2.4 — PartialOperators must demonstrate the deployed proxy/Node HTTP framing and trusted-forwarding configuration against ambiguous requests; source-level request tests cannot prove a public deployment.
V4.2.5 — PartialMaintainers must bound constructed outbound URI and header fields against each receiving service's accepted size; provider response caps do not establish that request-side property.
V5.2.2 — PartialImport parses and validates JSON content, while the file chooser's .json hint does not enforce extension/content agreement. Maintainers would need an explicit filename and content check for this control.
V5.4.1 — N/AExport uses a fixed browser Blob filename through anchor.download; it has no HTTP attachment response or user-submitted download filename. No Content-Disposition header is emitted or claimed.
V6.2.4 — PartialContext-word checks and optional breached-password screening do not prove that every registration/change rejects the top 3,000 policy-matching passwords. Maintainers need a guaranteed list or equivalent evidence.
V6.2.12 — PartialOperators must prove breached-password screening remains enabled where required; configuration can disable it.
V6.8.4 — PartialOperators must verify the named provider's live factor policy. Maintainers must verify returned authentication-strength and recency claims or apply a conservative fallback; deterministic application tests do not establish that assurance.
V6.3.8 — PartialGeneric messages alone do not prove indistinguishable response codes and timing across login, registration and recovery. Maintainers need differential boundary tests and timing assessment.
V6.3.3, V6.3.5, V6.3.7 — GapPassword-only access does not meet the multi-factor requirement, and suspicious-attempt and credential-change notices are absent; input hardening does not implement these capabilities.
V8.2.4 — Gap; V8.4.2 — PartialAdaptive device/risk authorization is absent, and freshness covers only the specified sensitive actions. Maintainers would need a separate product decision and enforcement tests to change this scope.
V16.2.2, V16.3.2, V16.4.2–V16.4.3 — PartialOperators must provide clock and external collector/ACL/retention evidence; maintainers would need additional event coverage for successful high-assurance decisions. Local safe-error tests do not prove those deployment controls.
V16.5.4 — PartialThe last-resort handler deliberately drains and terminates on an unhandled failure, then relies on supervisor restart. This fails closed but does not meet the control's literal continue-without-termination limb.
V16.1.1, V16.2.4 — PartialThe checked-in logging inventory does not establish deployed retention/access or show that the selected log processor can read and correlate each stream. Operators must supply processor and access evidence.

Interpretation ​

Password-only deployments cannot meet the ASVS Level 2 multi-factor requirement through CapacityLens. Google or Microsoft provider MFA may meet an agency policy when configured and tested there; CapacityLens cannot verify that provider policy. Breach screening can be disabled. A password-only deployment therefore does not meet V6.3.3 L2. A Gap in a Level 3-only requirement still documents a conscious higher-assurance boundary rather than an L2 failure. Partial/Gap L1/L2 controls remain real limitations, particularly optional authentication hardening, federated-provider proof, URL bearer links and deployment public-TLS/secret/log/storage evidence.

CapacityLens is open source under AGPL-3.0.