מדריכיםמפתחים

מפתחים

Application hardening

Maintainer reference for Next.js / client-facing hardening that complements DB authz.

Role resolution in the app

  • Proxy (src/proxy.ts): loads profiles.role for the authenticated user. On profile-fetch timeout, does not treat the user as a trusted teacher — fail closed for privileged routes.
  • Login / signup / callback: resolve role from profiles, never from user_metadata.
  • Server actions: prefer requireUser / requireTeacher / requireTeacherWorkspace from src/lib/auth/guards.ts.

guards.ts is a shared server helper module (not a "use server" actions barrel) so it is not exposed as client-callable actions by itself.

HTTP security headers

Configured in next.config.ts for /:path*:

HeaderPurpose
Content-Security-PolicyRestrict scripts, frames, connect, media, workers
X-Content-Type-Options: nosniffBlock MIME sniffing
X-Frame-Options: DENYClickjacking
Referrer-Policy: strict-origin-when-cross-originLimit referrer leakage
Permissions-PolicyDisable camera, mic, geolocation, payment
Strict-Transport-SecurityProduction only

Also: poweredByHeader: false.

CSP allows known needs (Supabase hosts, fonts, unpkg for pdf.js worker, talmud.dev frames). Tighten further when nonce-based CSP is wired.

Passwords

  • UI minimum: 8 characters (minLength={8}, placeholder «לפחות 8 תווים»)
  • Hebrew error copy aligns with that minimum (src/lib/utils/auth-errors.ts)

Known gap (not live)

Supabase leaked-password protection (Have I Been Pwned) requires a Pro plan. The project org is on Free — this is not enabled. Enable after upgrading; do not document it as active.

Havruta media uploads

  • Private bucket; MIME allowlist on upload (images / audio types enforced in havruta-media actions)
  • Clients receive signed URLs with TTL 2 hours (HAVRUTA_SIGNED_URL_TTL_SEC in src/lib/havruta/signed-media.ts)
  • Storage policies + app checks prevent arbitrary file types

Server Actions body size

Teacher PDF / page upload payloads can be large; experimental.serverActions.bodySizeLimit is raised to 10mb in next.config.ts for that pipeline — not a general public upload free-for-all.

Checklist for future PRs

  • New privileged actions call requireTeacher / requireTeacherWorkspace (or equivalent)
  • No new authz based on user_metadata.role
  • New storage buckets stay private + MIME-scoped
  • CSP updated if new third-party origins are required
  • Revisit leaked-password protection when on Pro