TUTORIAL 09

Security Audit

Your e-commerce app is preparing for launch. Run a complete security sweep before going live.

โฑ ~20 min ยท Hands-on

/agile-security-threat-model /agile-security-audit /agile-security-scan /agile-security-review /agile-code-tdd /agile-code-ci
Scenario

Your e-commerce application handles user accounts, payment processing, and order management. Launch is scheduled in two weeks. Before going live, the team must perform a comprehensive security audit to identify and remediate vulnerabilities. No critical or high-severity findings are allowed at launch.

Step 1: Threat Modeling with STRIDE

Before scanning for specific vulnerabilities, understand what you're protecting and how it could be attacked. STRIDE gives you a systematic framework.

/agile-security-threat-model

Asset Inventory

Assets Identified:
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  1. User data (PII, emails, addresses)
  2. Payment information (card tokens, billing)
  3. Session tokens (JWT, cookies)
  4. Admin panel access
  5. Order history and transaction logs

Attack Surface Mapping

Attack Surfaces:
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  ๐Ÿ”“ Login endpoint     POST /api/auth/login
  ๐ŸŒ Public API         GET/POST /api/products, /api/orders
  ๐Ÿ›ก๏ธ Admin panel        GET /admin/* (role-gated)
  ๐Ÿ’ณ Payment gateway    POST /api/checkout/pay
  ๐Ÿ“ฆ File uploads       POST /api/users/avatar

Apply STRIDE to each surface:

STRIDE Analysis โ€” Login Endpoint

STRIDE โ€” POST /api/auth/login
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  S โ€” Spoofing:           Credential stuffing, brute force
  T โ€” Tampering:          Manipulated login payloads
  R โ€” Repudiation:        No audit log of failed attempts
  I โ€” Info Disclosure:    Error messages reveal user existence
  D โ€” Denial of Service:  No rate limiting on login
  E โ€” Elevation:          SQL injection in username field

Risk Matrix

Risk Matrix โ€” Pre-Launch
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  Threat                  Likelihood  Impact    Risk
  SQL injection           High        Critical  ๐Ÿ”ด S0
  Missing rate limiting   High        High      ๐ŸŸ  S1
  Session token in URL    Medium      High      ๐ŸŸ  S1
  Verbose error messages  Medium      Medium    ๐ŸŸก S2
  Missing audit logs      Low         Medium    ๐Ÿ”ต S3
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Step 2: OWASP Top 10 Audit

Now scan the application against the OWASP Top 10 โ€” the industry standard checklist for web application security.

/agile-security-audit
OWASP Top 10 Audit โ€” e-commerce-app
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

A01: Broken Access Control ........ โœ… PASS
A02: Cryptographic Failures ....... โœ… PASS
A03: Injection .................... โŒ FAIL
A04: Insecure Design .............. โœ… PASS
A05: Security Misconfiguration .... โš ๏ธ WARNING
A06: Vulnerable Components ........ โŒ FAIL (see scan)
A07: Auth Failures ................ โš ๏ธ WARNING
A08: Data Integrity Failures ...... โœ… PASS
A09: Logging Failures ............. โš ๏ธ WARNING
A10: SSRF ......................... โœ… PASS

Findings:
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  ๐Ÿ”ด S0 โ€” SQL injection in search query
     Location: src/api/products/search.controller.ts:47
     Detail: User input concatenated directly into SQL query
     Fix: Use parameterized queries

  ๐ŸŸ  S1 โ€” Session tokens exposed in URL parameters
     Location: src/middleware/auth.ts:23
     Detail: JWT passed as ?token= query param, logged by proxies
     Fix: Move token to Authorization header or HttpOnly cookie

  ๐ŸŸก S2 โ€” Missing rate limiting on login endpoint
     Location: src/api/auth/login.controller.ts
     Detail: No throttle โ€” allows unlimited login attempts
     Fix: Add rate limiter (e.g., 5 attempts per minute)

  ๐Ÿ”ต S3 โ€” Verbose error messages in production
     Location: src/middleware/errorHandler.ts:12
     Detail: Stack traces and internal paths exposed in 500 errors
     Fix: Return generic error message in production mode
Launch Blockers

๐Ÿ”ด S0 (Critical) and ๐ŸŸ  S1 (High) findings block the launch. These must be remediated and verified before going live. No exceptions.

Step 3: Dependency CVE Scan

Third-party packages are a common attack vector. Scan all dependencies for known CVEs.

/agile-security-scan
Dependency CVE Scan โ€” e-commerce-app
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Packages scanned: 134
Vulnerabilities found: 3

  ๐Ÿ”ด Critical โ€” jsonwebtoken@8.5.1
     CVE-2022-23529: Insecure key retrieval
     Fix: upgrade to jsonwebtoken@9.0.0+

  ๐ŸŸก Medium โ€” lodash@4.17.20
     CVE-2021-23337: Prototype pollution in zipObjectDeep
     Fix: upgrade to lodash@4.17.21

  ๐ŸŸก Medium โ€” lodash@4.17.20
     CVE-2020-28500: ReDoS in trim/trimEnd
     Fix: upgrade to lodash@4.17.21

โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Action Required: 1 critical, 2 medium vulnerabilities
Critical CVE in JWT Library

The jsonwebtoken package handles authentication tokens. A critical CVE here means an attacker could forge valid tokens. Upgrade immediately.

Step 4: Focused Code Review

Run a security-focused review on the authentication and authorization code โ€” the highest-risk area of the application.

/agile-security-review
Security Code Review โ€” Auth Module
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

File: src/api/auth/login.controller.ts
  โŒ Line 22: Input not validated before use
     โ†’ Add Zod/Joi schema validation for email and password

  โŒ Line 35: Password compared with == instead of ===
     โ†’ Use timing-safe comparison (crypto.timingSafeEqual)

File: src/config/app.config.ts
  โŒ Line 8: JWT_SECRET hardcoded as "supersecret123"
     โ†’ Move to environment variable, use strong random secret

File: src/middleware/cors.ts
  โš ๏ธ Line 5: CORS allows origin "*"
     โ†’ Restrict to known frontend domains

โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Critical: 3  |  Warning: 1

Step 5: Triage All Findings

Consolidate every finding from the audit, scan, and review. Classify what blocks launch vs. what can wait.

Triage Summary

Launch Blockers (must fix NOW):
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  ๐Ÿ”ด S0  SQL injection in product search
  ๐Ÿ”ด CVE jsonwebtoken critical vulnerability
  ๐ŸŸ  S1  Session tokens exposed in URL
  ๐ŸŸ      Hardcoded JWT secret
  ๐ŸŸ      Missing input validation in auth

Post-Launch (track as tech debt):
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  ๐ŸŸก S2  Missing rate limiting on login
  ๐ŸŸก     lodash prototype pollution (2 CVEs)
  ๐ŸŸก     CORS wildcard origin
  ๐Ÿ”ต S3  Verbose error messages in production

Step 6: Fix Critical Findings with TDD

Write security tests first, then fix the code. This ensures the vulnerability cannot regress.

/agile-code-tdd

RED: Write Failing Security Tests

// test/security/sql-injection.test.ts
describe("SQL Injection Prevention", () => {
  it("rejects SQL in search query", async () => {
    const res = await request(app)
      .get("/api/products/search")
      .query({ q: "'; DROP TABLE products;--" });
    expect(res.status).toBe(400);
    expect(res.body.results).toBeUndefined();
  });

  it("sanitizes special characters in search", async () => {
    const res = await request(app)
      .get("/api/products/search")
      .query({ q: "shirt' OR '1'='1" });
    expect(res.status).toBe(200);
    expect(res.body.results).toHaveLength(0);
  });
});

// test/security/auth-tokens.test.ts
describe("Token Security", () => {
  it("rejects tokens passed as URL params", async () => {
    const res = await request(app)
      .get("/api/orders?token=valid.jwt.here");
    expect(res.status).toBe(401);
  });

  it("accepts tokens in Authorization header", async () => {
    const res = await request(app)
      .get("/api/orders")
      .set("Authorization", "Bearer valid.jwt.here");
    expect(res.status).toBe(200);
  });
});
Tests: 4 failing โŒ (expected โ€” RED phase)

GREEN: Fix the Vulnerabilities

// src/api/products/search.controller.ts โ€” FIXED
const results = await db.query(
  "SELECT * FROM products WHERE name ILIKE $1",
  [`%${sanitize(query)}%`]  // parameterized query
);

// src/middleware/auth.ts โ€” FIXED
// Removed: const token = req.query.token
const token = req.headers.authorization?.replace("Bearer ", "");

// src/config/app.config.ts โ€” FIXED
const JWT_SECRET = process.env.JWT_SECRET;
if (!JWT_SECRET) throw new Error("JWT_SECRET must be set");
Tests: 4 passing โœ… (GREEN phase)

Upgrade the vulnerable dependency:

npm install jsonwebtoken@9.0.2
npm install lodash@4.17.21

Step 7: Re-scan and Verify

Run the full pipeline and security scans again. Every blocker must be resolved.

/agile-code-ci
CI Pipeline โ€” security-fixes
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Build .................. โœ… PASS
Unit Tests ............. โœ… 156/156 passing
Integration Tests ...... โœ… 28/28 passing
Security Tests ......... โœ… 4/4 passing (new)
Lint ................... โœ… 0 issues
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Result: โœ… ALL CHECKS PASSED
/agile-security-scan
Dependency CVE Scan โ€” re-scan
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Packages scanned: 134
Vulnerabilities found: 0

โœ… CLEAN โ€” no known vulnerabilities
/agile-security-audit
Re-Audit Results:
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  ๐Ÿ”ด S0  SQL injection ............ โœ… RESOLVED
  ๐Ÿ”ด CVE jsonwebtoken ............. โœ… RESOLVED
  ๐ŸŸ  S1  Token in URL ............. โœ… RESOLVED
  ๐ŸŸ      Hardcoded secret ......... โœ… RESOLVED
  ๐ŸŸ      Missing input validation . โœ… RESOLVED

Launch Blockers Remaining: 0
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
โœ… CLEAR FOR LAUNCH
All Blockers Resolved

Every ๐Ÿ”ด S0 and ๐ŸŸ  S1 finding has been fixed and verified. The application is clear for launch.

Step 8: Track Remaining Items as Tech Debt

The ๐ŸŸก S2 and ๐Ÿ”ต S3 findings don't block launch, but they must not be forgotten. Create stories for the next sprint.

Tech Debt Stories Created

Sprint Backlog โ€” Next Sprint:
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
  ๐Ÿ“‹ SEC-001: Add rate limiting to login endpoint (๐ŸŸก S2)
     AC: Max 5 attempts per IP per minute, lockout after 10
  ๐Ÿ“‹ SEC-002: Restrict CORS to known domains (๐ŸŸก S2)
     AC: Only frontend.example.com allowed
  ๐Ÿ“‹ SEC-003: Sanitize error messages in production (๐Ÿ”ต S3)
     AC: No stack traces or file paths in error responses

Security Audit Flow

๐ŸŽฏ
/agile-security-threat-model STRIDE analysis
๐Ÿ”
/agile-security-audit OWASP Top 10
๐Ÿ“ฆ
/agile-security-scan CVE check
๐Ÿ‘๏ธ
/agile-security-review code review
๐Ÿ”ง
/agile-code-tdd fix + test
๐Ÿ”„
Re-scan verify clean

What You Practiced

Knowledge Check

Which findings block a launch?