Threat-model trust boundaries before applying random security checklists.
Course navigationPhase 29⌄
Security Hardening
Threat-model TaskFlow and apply layered controls for access control, input/output safety, headers, abuse, secrets, uploads, dependencies, and configuration.
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.
Principles to keep while coding
Validate and authorize every sensitive server operation even if the frontend already restricts the UI.
Keep secrets out of source control, client bundles, logs, and error responses.
Use layered defenses for common web risks such as injection, broken access control, unsafe uploads, and misconfiguration.
Guided phase lab
Do these in order. Each step should end with evidence before the next one starts.
- 01
List sensitive assets and trust boundaries before selecting mitigations.
- 02
Run an IDOR/broken-access-control test by changing resource IDs as another user.
- 03
Review all external input boundaries and confirm validation plus parameterized/ORM-safe persistence.
- 04
Review rendering/output paths for XSS assumptions and add sensible content/security headers.
- 05
Check secret locations, source control, logs, client bundles, CI, and deployment settings.
- 06
Add abuse controls where justified and write security regression tests for discovered cases.
Failures you should know how to diagnose
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.
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.
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.
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.
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.
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
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
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
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
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.
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
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
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
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
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
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
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
Guided Build Lab
Purpose Threat-model TaskFlow and apply layered controls for access control, input/output safety, headers, abuse, secrets, uploads, dependencies, and configuration.
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.
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?
Mastery Capstone Lab
Integrate Phase 29 without following a transcript.
Exercises that increase independence
List sensitive assets and trust boundaries before selecting mitigations.
Review all external input boundaries and confirm validation plus parameterized/ORM-safe persistence.
reproduce and diagnose — Security checklist with no threat model.
deliver Security baseline checklist plus concrete tests for the most important abuse cases.
Can describe assets and attackers and Can test broken access control.
Do not leave the phase only because you reached the bottom
Phase exit criteria
Scenario and concept quiz
These questions test engineering choices rather than whether you remember a lesson title.
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 shippingreference/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