SuperAPI AI Directory

application-security-requirements

Security & auditing

View repository

Updated 10-16 05:01

About this skill

Application Security Requirements

Apply these rules when reviewing the security implications of any code change in this project. The framing is OWASP Top 10 mapped onto this project's specific stack — Next.js App Router, Payload CMS (SQLite/Turso, Vercel Blob), Remark/Shiki markdown, Vercel hosting, Sentry, Mixpanel.

Secret and Environment-Variable Handling

See secret-handling.md for:

  • No literal secret committed (Payload secret, Sentry DSN with auth token, Vercel Blob token, Turso auth token, test user password)
  • process.env.* accessed only inside the project's whitelisted env-access files
  • NEXT_PUBLIC_* prefix used only for values intentionally exposed to the browser
  • .env.local is gitignored; example only in .env.example

Input Validation

See input-validation.md for:

  • All route.ts handlers validate and coerce request inputs before passing them to Payload or fetch
  • All params / searchParams are treated as untrusted (they reach the server as Promise<unknown>-shaped at runtime)
  • Repository where clauses receive sanitized values (no array-coercion bypass on slug)
  • Repository return values are parsed through the Zod schemas in app/(app)/_/repositories/payload-types.ts before reaching components

Access Control

See access-control.md for:

  • Each Payload collection / global has an explicit access configuration appropriate for its data sensitivity
  • Draft content is gated by the _status: { equals: "published" } filter when draft is not requested
  • The users collection's auth lock settings are not weakened
  • New route.ts mutation endpoints (e.g., the /posts/caches revalidation route) are protected against unauthenticated abuse

Privacy and Exposure Control

See privacy-and-exposure.md for:

  • Draft, preview, admin-only, and unpublished content cannot leak through public routes, metadata, JSON-LD, sitemap, robots, or image routes
  • Public media URLs expose only intentionally public assets and do not reveal private storage tokens or internal identifiers
  • Sentry and Mixpanel changes do not capture unnecessary PII, secrets, draft content, or CMS-authored private fields
  • Client-exposed environment variables, analytics event properties, and error context are intentionally public

XSS in Markdown Rendering

See xss-in-markdown.md for:

  • The remarkParse allowDangerousProtocol: true setting in app/(app)/_/helpers/markdown.ts is acknowledged and any new HAST element mapping does not pass user-controlled URLs into dangerouslySetInnerHTML or unsanitized attributes
  • Custom directive nodes (currently webembed) only emit attributes that React will encode
  • New components added to the renderer's defaultComponents map encode untrusted children safely
  • rehypeReact is not bypassed (no manual HAST-to-string interpolation that skips React's encoding)

SSRF and Embed Fetching

See ssrf-and-embeds.md for:

  • getWebEmbedMetadata (which fetch-es arbitrary URLs from CMS-authored content) does not let internal-network URLs through to production
  • The Image component's unoptimized flag is not used when the URL is user-controlled and could point at internal hosts
  • New CMS-author-controlled URLs that flow into a fetch call go through an allowlist or a hostname check
  • New images.remotePatterns entries in next.config.ts are tightly scoped

Auth and Session Management

See auth-and-session.md for:

  • Payload's auth lockout settings (lockTime, maxLoginAttempts on the users collection) are not relaxed
  • Live preview / draft state is reachable only through Payload's auth path, not via a query-string bypass
  • Sentry sendDefaultPii: true exposure is acknowledged when adding new identifiers/contexts

Supply Chain

See supply-chain.md for:

  • New npm dependencies justify their addition per development-guidelines › change-management
  • New dependencies are reasonably popular, maintained, and platform-agnostic
  • Lockfile is updated; transitive additions are inspected for known-vulnerable versions
  • No postinstall / prepare script in a new dependency runs unexpected code