We already know what the ASVS is and that BazarNube is aiming for Level 2. It is time to open the catalogue and work with the real requirements. In this lesson we will walk through the requirement chapters most relevant to a web application like BazarNube, learn to read a verifiable requirement precisely and —most usefully of all— map the Top Ten findings from module 3 to concrete ASVS requirements. That mapping is what turns BazarNube's scattered backlog into a verifiable checklist ordered by chapters.

Contents

  1. How to read a verifiable requirement
  2. V2 – Authentication
  3. V3 – Session management
  4. V4 – Access control
  5. V5 – Validation, sanitization and encoding
  6. V6 – Stored cryptography
  7. V7 – Error handling and logging
  8. V8/V9 – Data protection and communications
  9. V14 – Configuration
  10. Map: BazarNube Top Ten findings → ASVS requirements

How to read a verifiable requirement

Before walking through chapters, let us fix the reading method. An ASVS requirement is read by identifying four things:

V5.3.3  "Verify that context-aware output encoding is performed close
         to or by the interpreter it is intended for."
         Levels: L1 L2 L3   CWE-116

1. WHAT it states       -> "context-based output encoding is done"
2. HOW it is checked     -> review the rendering/template code
3. AT WHICH LEVEL it applies -> L1, L2 and L3 (mandatory from L1)
4. WHICH weakness it covers  -> CWE-116 (improper output encoding)

Practical rule: if you cannot answer "pass / fail / not applicable" after reading it, you have not finished verifying it. Each requirement is a test case, not a recommendation. With that method, let us walk through the key chapters.

V2 – Authentication

It gathers the requirements about credentials, their lifecycle and protection against abuse. It covers the territory of A07 (Authentication failures) in the Top Ten.

Requirement Text (summarized) Level
V2.1.1 Passwords are at least 12 characters long L1–L3
V2.1.7 Passwords are checked against lists of compromised ones L1–L3
V2.2.1 Anti-automation controls exist (brute force, credential stuffing) L1–L3

Example of verifying V2.1.7 in BazarNube's Node backend:

// V2.1.7: reject passwords present in breached lists
const pwnedCount = await checkBreachedPassword(password); // e.g. k-anonymity
if (pwnedCount > 0) {
  return res.status(400).json({
    error: 'This password appears in known breaches. Choose another one.'
  });
}
// V2.1.1: minimum length
if (password.length < 12) {
  return res.status(400).json({ error: 'Minimum 12 characters.' });
}

V3 – Session management

Requirements about how session tokens are created, transported, expired and invalidated. It complements V2 in the territory of A07.

Requirement Text (summarized) Level
V3.2.1 New session tokens are generated after authenticating (anti-fixation) L1–L3
V3.3.1 Logout and expiration really invalidate the token L1–L3
V3.4.1 Session cookies carry the Secure, HttpOnly and SameSite attributes L1–L3

Example of a session cookie configuration that satisfies V3.4.1 in Express:

// V3.4.1: hardened session cookie
res.cookie('sid', sessionId, {
  httpOnly: true,   // not accessible from JavaScript (mitigates theft via XSS)
  secure: true,     // only sent over HTTPS
  sameSite: 'lax',  // mitigates CSRF on cross-site navigation
  maxAge: 1000 * 60 * 30 // expiration (supports V3.3.x)
});

V4 – Access control

The authorization chapter: who can access what. It covers the territory of A01 (Broken access control), including the IDOR that BazarNube suffered.

Requirement Text (summarized) Level
V4.1.1 Access control rules are enforced on a trusted server L1–L3
V4.1.3 Principle of least privilege: only what is authorized is accessed L1–L3
V4.2.1 Resource ownership is verified before access (anti-IDOR) L1–L3

Example of verifying V4.2.1 by fixing the IDOR on BazarNube's orders:

// V4.2.1: check resource ownership, don't trust the client-supplied ID
const order = await Order.findById(req.params.id);
if (!order || order.userId !== req.user.id) {
  return res.status(404).end(); // 404, not 403, to avoid revealing existence
}
res.json(order);

V5 – Validation, sanitization and encoding

The chapter that concentrates the defence against injection and XSS. It covers the territory of A03 (Injection) and of the XSS from module 3.

Requirement Text (summarized) Level
V5.1.1 Input is validated against a schema/allow list L1–L3
V5.3.3 Context-aware output encoding (anti-XSS) L1–L3
V5.3.4 Parameterized queries / a safe ORM are used (anti-SQL injection) L1–L3

Example of V5.3.4 replacing BazarNube's SQL concatenation:

// BAD (injection): const q = `SELECT * FROM products WHERE name='${name}'`;
// V5.3.4: parameterized query
const { rows } = await db.query(
  'SELECT * FROM products WHERE name = $1',
  [name]
);

V6 – Stored cryptography

Requirements about encryption at rest, key management and randomness. It covers the territory of A02 (Cryptographic failures).

Requirement Text (summarized) Level
V6.2.1 Sensitive data is encrypted at rest L1–L3
V6.2.3 Approved, non-obsolete algorithms and modes are used L2–L3
V6.4.1 Keys and secrets are managed with a secure store (not in code) L2–L3

Example of V6.4.1: secrets do not live in the repository.

// V6.4.1: the key is read from a secret manager / environment variable,
// never hardcoded in the source code
const dbKey = process.env.DB_ENCRYPTION_KEY; // injected by the secret store
if (!dbKey) throw new Error('DB_ENCRYPTION_KEY is missing from the environment');

V7 – Error handling and logging

Requirements about logging security events without leaking sensitive data. It covers the territory of A09 (Logging and monitoring failures).

Requirement Text (summarized) Level
V7.1.1 No sensitive data (credentials, cards) is logged L1–L3
V7.2.1 Relevant security events are logged (login, access denied) L2–L3
V7.3.1 Logs are protected against tampering and are analyzable L2–L3
// V7.2.1: log a security event; V7.1.1: no sensitive data
logger.security('login_failed', {
  userHash: hash(email),   // not the plaintext email; never the password
  ip: req.ip,
  ts: Date.now()
});

V8/V9 – Data protection and communications

  • V8 (Data protection): minimization, retention, protection of sensitive data on the client and in memory. It covers part of A02 and A04 (Insecure design).
  • V9 (Communications): well-configured TLS, encryption in transit, no weak protocols.
Requirement Text (summarized) Level
V8.1.1 Sensitive data is protected against unauthorized caching L2–L3
V8.3.1 Retention of personal data is minimized and controlled L2–L3
V9.1.1 All communication uses TLS; no fallback to plaintext L1–L3
V9.1.2 Current TLS versions and suites are used; no obsolete protocols L2–L3

V14 – Configuration

Deployment hardening: security headers, dependencies, secrets, default values. It covers A05 (Security misconfiguration) and A06 (Vulnerable components).

Requirement Text (summarized) Level
V14.3.2 Unnecessary default configurations and accounts are removed L1–L3
V14.4.1 HTTP security headers are sent (CSP, HSTS, X-Content-Type-Options...) L1–L3
V14.2.1 Dependencies are up to date and free of known vulnerabilities L1–L3
// V14.4.1: security headers with helmet in Express
app.use(helmet({
  contentSecurityPolicy: { directives: { defaultSrc: ["'self'"] } },
  hsts: { maxAge: 31536000, includeSubDomains: true }
}));

Map: BazarNube Top Ten findings → ASVS requirements

This is the lesson's central deliverable: turning the module 3 backlog (organized by risks A01–A10) into verifiable ASVS requirements (organized by V chapters). Each row takes a real BazarNube finding and anchors it to the requirements that must be verified.

BazarNube finding (M3) Top Ten risk ASVS requirements to verify Chap.
IDOR on /orders/:id A01 V4.1.1, V4.2.1 V4
Secrets and encryption key in the repo A02 V6.2.1, V6.4.1 V6
Payment data not encrypted at rest A02 V6.2.1, V8.1.1 V6/V8
SQL by concatenation in search A03 V5.1.1, V5.3.4 V5
No threat modeling in checkout A04 V1.1.x V1
No security headers / insecure defaults A05 V14.3.2, V14.4.1 V14
Library with a known CVE A06 V14.2.1 V14
Reflected XSS in the search box A03/XSS V5.3.3, V5.3.4 V5
Weak passwords and no anti-brute-force A07 V2.1.1, V2.1.7, V2.2.1 V2
Session not invalidated on logout A07 V3.3.1, V3.4.1 V3
No logging of security events A09 V7.2.1, V7.3.1 V7
SSRF in "image from URL" A10 V5.2.6, V12.6.x V5/V12

With this map, BazarNube no longer has "a pile of loose fixes": it has an ASVS checklist by chapters, with an associated level and a verifiable status for each row. That is the direct input for the next lesson, where we will turn it into an implementation plan.

graph LR
  TT[Top Ten findings M3] --> MAP[Mapping to ASVS requirements]
  MAP --> CHK[Checklist by V chapters]
  CHK --> VER[Verification pass fail]

Common Mistakes and Tips

  • Reading the requirement as advice, not as a test. If after reading it you cannot say pass/fail, you have not verified it; you still need to look at code or test.
  • Validating only on the client. V4.1.1 and V5.1.1 require enforcing access control and validation on the server; the front end is a UX aid, not a security control.
  • Confusing output encoding with input validation. They are distinct requirements (V5.3 vs V5.1) and both are needed: validating input does not exempt you from encoding output.
  • Storing secrets in the repository. V6.4.1 explicitly forbids it; use a secret store or injected environment variables.
  • Tip: work chapter by chapter, not by random requirement. Finishing all of V2 gives a far more useful compliance picture than pecking at loose requirements from several chapters.

Exercises

Exercise 1. Take the "reflected XSS in the search box" finding from BazarNube. Indicate which ASVS chapter(s) and requirement(s) you would map it to and explain why both input validation and output encoding come into play.

Exercise 2. Read this requirement and say what you would check in BazarNube's code to mark it "pass": "V3.4.1 – Verify that session cookies use the Secure, HttpOnly and SameSite attributes."

Exercise 3. The "secrets in the repository" finding was mapped to V6.4.1. Propose two concrete pieces of evidence you would present to an auditor to demonstrate that BazarNube now meets that requirement.

Solutions

Solution 1. It maps to chapter V5 (Validation, sanitization and encoding), mainly to V5.3.3 (context-aware output encoding) and, complementarily, to V5.1.1 (input validation). Both come into play because they are distinct, cumulative defences: validating input reduces the surface (rejecting unexpected characters/structures), but it is not enough, because legitimate data may contain dangerous characters; the decisive protection against XSS is encoding output according to the context (HTML, attribute, JS) at the point of rendering. Meeting only one leaves a gap; the ASVS demands both.

Solution 2. I would look in the code where the session cookie is emitted (for example the express-session config or res.cookie('sid', ...)) and check that all three attributes are set: httpOnly: true (not accessible from JS, mitigates theft via XSS), secure: true (only over HTTPS) and sameSite (lax or strict, mitigates CSRF). If all three are present on every path that creates the cookie, the requirement is marked pass; if any is missing or a route emits the cookie without them, fail.

Solution 3. (1) Configuration evidence: a screenshot of the secret manager / environment variables showing that DB_ENCRYPTION_KEY and the other secrets are injected at runtime, plus the code snippet that reads them from process.env with no hardcoded values. (2) Process/historical evidence: the result of a secret scan (for example a secret scanner in CI) over the current repository returning zero findings, and confirmation that the old exposed keys were rotated. The two together demonstrate that the secrets are neither in the code nor still the ones that were exposed.

Conclusion

The ASVS requirements are organized into thematic chapters —V2 authentication, V3 sessions, V4 access control, V5 validation and encoding, V6 cryptography, V7 logging, V8/V9 data and communications, V14 configuration— and each one is read as a test case with a pass/fail/not-applicable answer. The most valuable thing for BazarNube has been mapping the module 3 Top Ten findings to concrete ASVS requirements, transforming a backlog of loose risks into a checklist verifiable by chapters and levels.

We have the standard, the target level (L2) and the mapped checklist. What is missing is what turns all this into results: how to integrate it into the project's day-to-day. In the final lesson of the module, 04-04 Implementing ASVS in Projects, we will see how to use the checklist as acceptance criteria, when to verify manually or automatically, how to leave evidence and traceability, and we will lay out a practical step-by-step plan for BazarNube's backlog.

OWASP Course: Guidelines and Standards for Web Application Security

Module 1: Introduction to OWASP

Module 2: Main OWASP Projects

Module 3: OWASP Top Ten 2021 in Depth

Module 4: OWASP ASVS (Application Security Verification Standard)

Module 5: OWASP SAMM (Software Assurance Maturity Model)

Module 6: OWASP ZAP (Zed Attack Proxy)

Module 7: Best Practices and Recommendations

Module 8: Practical Exercises and Case Studies

Module 9: Assessment and Certification

© Copyright 2026. All rights reserved