Feature access is gated on subscription status
Why it matters
Hiding UI elements from free users while leaving the underlying API endpoint open is security theater. Any user with browser dev tools can call the API directly, bypassing the paywall entirely. OWASP A01 (Broken Access Control) and CWE-284 (Improper Access Control) cover this exactly. Every premium feature needs enforcement at both layers: the UI gate for user experience, the API gate as the actual security boundary. NIST AC-3 (Access Enforcement) requires that access controls are applied at the resource, not just the interface.
Severity rationale
High because UI-only gating leaves every premium API endpoint exploitable by any authenticated user with a basic HTTP client.
Remediation
Add server-side subscription checks to every API route that serves premium data or actions. The UI gate controls display; the API gate is the real enforcement.
// app/api/reports/export/route.ts
export async function GET(req: Request) {
const session = await getServerSession()
const user = await db.user.findUnique({
where: { id: session?.userId },
select: { plan: true, subscription_status: true }
})
if (!user || user.plan !== 'pro' || user.subscription_status !== 'active') {
return Response.json({ error: 'Upgrade required' }, { status: 402 })
}
// serve premium content
}
For each premium feature, verify both: the UI renders an upgrade prompt for free users, AND the API returns 402 for unauthenticated or free-tier requests.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Billing & Payments Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-284 — Improper Access Control
- owasp:2021 · A01 — Broken Access Control
- nist:rev5 · AC-3 — Access Enforcement
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-billing·automated