Course navigationPhase 29
Volume 08 · Phase 29

Security Hardening

Threat-model TaskFlow and apply layered controls for access control, input/output safety, headers, abuse, secrets, uploads, dependencies, and configuration.

16lessons + labs
4klesson words
11source references
What you will ship

Phase outcome and project increment

Learning outcome

Threat-model TaskFlow and apply layered controls for access control, input/output safety, headers, abuse, secrets, uploads, dependencies, and configuration.

Concrete deliverable

Security baseline checklist plus concrete tests for the most important abuse cases.

Figure 29.1 — Where this phase lives in TaskFlow
asset/trust boundary
abuse case
preventive control
detection/logging
test
residual risk
Trace the flow left-to-right for implementation and right-to-left for debugging. At every arrow, ask what data crosses the boundary and what proves it is trustworthy.
Instructor mental model

Principles to keep while coding

01

Threat-model trust boundaries before applying random security checklists.

02

Validate and authorize every sensitive server operation even if the frontend already restricts the UI.

03

Keep secrets out of source control, client bundles, logs, and error responses.

04

Use layered defenses for common web risks such as injection, broken access control, unsafe uploads, and misconfiguration.

Code-along path

Guided phase lab

Do these in order. Each step should end with evidence before the next one starts.

  1. 01

    List sensitive assets and trust boundaries before selecting mitigations.

  2. 02

    Run an IDOR/broken-access-control test by changing resource IDs as another user.

  3. 03

    Review all external input boundaries and confirm validation plus parameterized/ORM-safe persistence.

  4. 04

    Review rendering/output paths for XSS assumptions and add sensible content/security headers.

  5. 05

    Check secret locations, source control, logs, client bundles, CI, and deployment settings.

  6. 06

    Add abuse controls where justified and write security regression tests for discovered cases.

Debugging studio

Failures you should know how to diagnose

Failure drill 1

Security checklist with no threat model

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 2

Trusting hidden buttons as protection

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 3

Secrets printed to logs/build output

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 4

Rate limiter treated as authentication or authorization

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Watch-order style

Lessons

The source chapters come first. Every phase now ends with a guided build, a debugging workshop, and an independent challenge so reading turns into transferable skill.

01

Threat Model and Security Baseline

Threat Model and Security Baseline TaskFlow - Full Stack Developer 2026 Start from assets and abuse cases TaskFlow threat-model loop Asset Entry point Abuse case Control what matters? where

2 min
02

HTTP Security Headers and CSP

HTTP Security Headers and CSP TaskFlow - Full Stack Developer 2026 Fastify security headers pnpm --filter api add @fastify/helmet@13.1.1 // main.ts - register before routes are exposed const

2 min
03

Rate Limiting and Abuse Controls

Rate Limiting and Abuse Controls TaskFlow - Full Stack Developer 2026 Use rate limits as one control ThrottlerModule.forRoot([ { name: "short", ttl: 1_000, limit: 10 }, { name: "minute", ttl

2 min
04

Input Validation Request Limits and Injection

Input Validation, Request Limits and Injection Prevention TaskFlow - Full Stack Developer 2026 Phase 12 remains the boundary Zod server validation is now hardened with explicit maximum lengt

2 min
05

XSS Output Handling and Content Security

XSS, Output Handling and Content Security TaskFlow - Full Stack Developer 2026 React helps, but escape hatches matter • Render user text as text; React escapes ordinary string interpolation.

2 min
06

CORS CSRF and Browser Trust Boundaries

CORS, CSRF and Browser Trust Boundaries TaskFlow - Full Stack Developer 2026 Match controls to credential transport Browser security boundaries Browser Next.js NestJS Postgres untrusted clie

2 min
07

Authentication Session and Authorization Abuse

Authentication, Session and Authorization Abuse TaskFlow - Full Stack Developer 2026 Hardening the existing chain Supabase JWT -> verify signature -> verify expected issuer -> verify audienc

2 min
08

Secrets Configuration and Environment Separation

Secrets, Configuration and Environment Separation TaskFlow - Full Stack Developer 2026 Classify configuration • Public: Supabase project URL / publishable browser key where intended. • Secre

2 min
09

File Upload and Storage Hardening

File Upload and Storage Hardening TaskFlow - Full Stack Developer 2026 Phase 27 gets an adversarial review • Keep private bucket default. • Authorize before issuing an upload intent or signe

2 min
10

Database Tenant and Data Protection

Database, Tenant and Data Protection TaskFlow - Full Stack Developer 2026 Preserve the authoritative boundary • Prisma migrations only; no manual production schema drift. • Foreign keys/uniq

2 min
11

Dependency Supply Chain Logging and Error Hardening

Dependency, Supply Chain, Logging and Error Hardening TaskFlow - Full Stack Developer 2026 Dependency hygiene • Keep lockfiles committed and reproducible. • Run pnpm audit/advisory review, b

2 min
12

Hands On Lab and Phase Exit

Hands-On Security Hardening Lab and Phase Exit TaskFlow - Full Stack Developer 2026 Lab 1 - Headers • Install @fastify/helmet 13.1.1 and inspect API response headers. • Add a conservative Ne

2 min
LAB

Guided Build Lab

Purpose Threat-model TaskFlow and apply layered controls for access control, input/output safety, headers, abuse, secrets, uploads, dependencies, and configuration.

3 min
LAB

Debugging Workshop

Goal Learn to diagnose this phase's failures systematically instead of reinstalling packages, changing random configuration, or copying a fix without understanding it.

2 min
LAB

Phase Synthesis & Independent Challenge

Mission Rebuild the capability of Phase 29 without following the exact code line-by-line. The goal is transfer: can you use the ideas when the variable names, UI, or route shape changes?

2 min
LAB

Mastery Capstone Lab

Integrate Phase 29 without following a transcript.

2 min
Practice ladder

Exercises that increase independence

Guided

List sensitive assets and trust boundaries before selecting mitigations.

Practice

Review all external input boundaries and confirm validation plus parameterized/ORM-safe persistence.

Debug

reproduce and diagnose — Security checklist with no threat model.

Independent

deliver Security baseline checklist plus concrete tests for the most important abuse cases.

Explain-back

Can describe assets and attackers and Can test broken access control.

Mastery gate

Do not leave the phase only because you reached the bottom

Phase exit criteria

Knowledge check

Scenario and concept quiz

These questions test engineering choices rather than whether you remember a lesson title.

0/0 correct · 0/8 answered
01Which practice best matches Phase 29's engineering goal?
02Which practice best matches Phase 29's engineering goal?
03Which practice best matches Phase 29's engineering goal?
04Which practice best matches Phase 29's engineering goal?
05You are working through the Phase 29 lab. Which next action is the most disciplined step?
06You are working through the Phase 29 lab. Which next action is the most disciplined step?
07You are working through the Phase 29 lab. Which next action is the most disciplined step?
08You are working through the Phase 29 lab. Which next action is the most disciplined step?
Source snapshot

Reference files

Attempt the work first. Use snapshots to compare a checkpoint, not as a substitute for understanding.

reference/TaskFlow_Security_Hardening_Snapshot/README.md
# TaskFlow Phase 29 Security Hardening Snapshot

Reference artifacts for the production hardening pass. Keep these controls aligned with the real deployment topology and verify them with tests.
reference/TaskFlow_Security_Hardening_Snapshot/SECURITY_CHECKLIST.md
# TaskFlow security hardening checklist

## HTTP / browser
- HTTPS only in production
- security headers verified
- CORS exact origins, methods and headers
- CSP designed/tested for deployed Next.js app
- no state-changing GET endpoints

## Identity / authorization
- JWT signature + issuer/audience/expiry verified
- authSubject mapping unique
- resource queries tenant-scoped
- 401/403/404 behavior tested
- role escalation denied

## Input / output
- server Zod validation on every untrusted body/query/path
- lengths/ranges/enums bounded
- React text rendering by default
reference/TaskFlow_Security_Hardening_Snapshot/SOURCES.md
- OWASP ASVS 5.0.0: https://owasp.org/projects/asvs
- OWASP Input Validation: https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html
- OWASP XSS Prevention: https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
- OWASP CSRF Prevention: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
- OWASP HTTP Headers: https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html
- OWASP REST Security: https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
- OWASP File Upload: https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
- OWASP Logging: https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html
- OWASP Secrets Management: https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
- NestJS Rate Limiting: https://docs.nestjs.com/security/rate-limiting
- @fastify/helmet: https://www.npmjs.com/package/@fastify/helmet
- @nestjs/throttler: https://www.npmjs.com/package/@nestjs/throttler
- Next.js Support Policy: https://nextjs.org/support-policy
reference/TaskFlow_Security_Hardening_Snapshot/THREAT_MODEL.md
# TaskFlow threat model

Assets: authentication sessions, tenant business data, attachments, secrets, authorization decisions, audit/log evidence, service availability.

Entry points: Next.js pages/actions, NestJS HTTP API, Supabase Auth, Realtime, Storage signed uploads/downloads, PostgreSQL, deployment configuration.

Representative abuse cases:
- stolen/replayed access token
- cross-workspace object ID tampering
- brute-force / request flooding
- XSS through user content
- CSRF against cookie-authenticated flows
- malicious/oversized upload
- service-role key leaked to browser/logs
- dependency vulnerability left unpatched
reference/TaskFlow_Security_Hardening_Snapshot/VERSION_LOCK.md
- @fastify/helmet: 13.1.1
- @nestjs/throttler: 6.5.0
- OWASP ASVS: 5.0.0
- Next.js: 16.x Active LTS
- NestJS: 12.x
- Fastify: 5.x
reference/TaskFlow_Security_Hardening_Snapshot/apps/api/.env.security.example
WEB_ORIGIN=http://localhost:3000
DATABASE_URL=
SUPABASE_URL=
SUPABASE_SERVICE_ROLE_KEY=

# Never prefix server secrets with NEXT_PUBLIC_.
reference/TaskFlow_Security_Hardening_Snapshot/apps/api/install-security.ps1
pnpm --filter api add @fastify/helmet@13.1.1 @nestjs/throttler@6.5.0
reference/TaskFlow_Security_Hardening_Snapshot/apps/api/src/main.security-example.ts
import helmet from "@fastify/helmet";

// After NestFactory.create<NestFastifyApplication>(...)
const fastify = app.getHttpAdapter().getInstance();
await fastify.register(helmet, {
  global: true,
  // The API returns JSON. Define the web-page CSP at the Next.js layer.
  contentSecurityPolicy: false,
});

app.enableCors({
  origin: [process.env.WEB_ORIGIN!],
  methods: ["GET", "POST", "PATCH", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization"],
});
reference/TaskFlow_Security_Hardening_Snapshot/apps/api/src/security/security.module.ts
import { Module } from "@nestjs/common";
import { APP_GUARD } from "@nestjs/core";
import { ThrottlerGuard, ThrottlerModule } from "@nestjs/throttler";

@Module({
  imports: [
    ThrottlerModule.forRoot([
      { name: "short", ttl: 1_000, limit: 10 },
      { name: "minute", ttl: 60_000, limit: 120 },
    ]),
  ],
  providers: [{ provide: APP_GUARD, useClass: ThrottlerGuard }],
  exports: [ThrottlerModule],
})
export class SecurityModule {}
reference/TaskFlow_Security_Hardening_Snapshot/apps/web/next.config.security-example.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  async headers() {
    return [{
      source: "/(.*)",
      headers: [
        { key: "X-Content-Type-Options", value: "nosniff" },
        { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
        { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
        { key: "X-Frame-Options", value: "DENY" },
      ],
    }];
  },
};

export default nextConfig;

// CSP intentionally omitted from this generic snapshot.
// Build/test a deployment-specific nonce/hash policy instead of shipping
reference/TaskFlow_Security_Hardening_Snapshot/tests/security-hardening-test-matrix.md
# Phase 29 security test matrix

## Headers
- API emits expected security headers
- Next.js emits nosniff/referrer/frame policy

## Rate limiting
- burst beyond route policy -> 429
- trusted proxy configuration preserves intended client tracker

## Input / errors
- oversized title/search/body rejected
- unknown fields rejected
- public 500 contains no stack/SQL/secret

## Authentication / authorization
- missing/expired/wrong-project token -> 401
- cross-workspace ID -> scoped 404/deny
- MEMBER role escalation -> forbidden