Authenticated API endpoints without explicit Cache-Control: no-store headers can be cached by a shared CDN or proxy, serving one user's private data — billing details, profile information, personal records — to the next user who hits the same cache key. This maps to CWE-524 (use of cache-containing sensitive information) and OWASP A02:2021 (cryptographic failures in data protection). Mutation endpoints cached by a CDN can also return stale success responses to clients while the actual operation does not re-execute.
Low because most CDN configurations default to not caching JSON API responses, but any misconfiguration exposes authenticated user data to other users sharing the same cache.
Add explicit Cache-Control headers in app/api/ route responses based on endpoint type. In Next.js App Router, set them in the Response constructor:
// Mutation endpoints and authenticated user-data endpoints
return new Response(JSON.stringify(data), {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-store',
},
})
// Public static data endpoints (e.g., config, pricing)
return new Response(JSON.stringify(data), {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'public, max-age=300, stale-while-revalidate=600',
},
})
Alternatively, set Cache-Control: no-store for all /api/ routes in next.config.ts headers config and override only where caching is intentional.
saas-api-design.api-docs.api-cache-headerslowCache-Control headers in route responses, Next.js revalidate config on API routes, platform-level caching config. Specifically check: (1) Do mutation endpoints (POST/PUT/PATCH/DELETE) include Cache-Control: no-store or equivalent to prevent caching? (2) Do cacheable GET endpoints (e.g., public config, static lists) include appropriate cache directives? (3) Do authenticated user-specific endpoints include Cache-Control: private or no-store?no-store or no-cache headers. Ideally, GET endpoints that return public static data use appropriate max-age or stale-while-revalidate headers.public cache directives (exposing user data to shared caches).Cache-Control: no-store on all /api/ routes.app/api/ route responses based on their characteristics. For any route that mutates data: Cache-Control: no-store. For any route returning user-specific data: Cache-Control: private, no-store. For public GET endpoints with static or infrequently changing data: Cache-Control: public, max-age=300, stale-while-revalidate=600. In Next.js App Router, set these in the route handler response: return new Response(JSON.stringify(data), { headers: { 'Cache-Control': 'no-store' } }). Incorrect caching of authenticated endpoints can cause user data leakage through shared CDN caches.