System access limited to authorized users and processes
Why it matters
CMMC 2.0 AC.L1-3.1.1 (NIST 800-171r2 3.1.1) requires that only authorized users and processes access organizational systems. Without enforced authentication on every sensitive route and API endpoint, any unauthenticated actor — a misconfigured crawler, a SSRF exploit, or a direct URL request — can read or exfiltrate Federal Contract Information. A single unguarded API endpoint in a DoD contractor's system is enough to trigger a CMMC assessment failure and jeopardize contract eligibility. CWE-306 (Missing Authentication for Critical Function) and OWASP A01 name this as the highest-severity access control failure class.
Severity rationale
Critical because unauthenticated route access exposes FCI to any network-reachable requester with zero credential requirements.
Remediation
Lock every API route and server-rendered page that touches FCI behind an authentication check. In middleware.ts, define an explicit allowlist of public paths and redirect all unmatched requests without a valid session:
// middleware.ts
const PUBLIC_PATHS = ['/', '/login', '/signup', '/api/auth']
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
const isPublic = PUBLIC_PATHS.some(p => pathname.startsWith(p))
if (!isPublic && !request.cookies.get('session')) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
}
Verify the matcher pattern does not create bypass gaps for /api/* paths — test with a tool like curl -s against each protected route without a cookie.
Detection
-
ID:
authorized-access -
Severity:
critical -
CMMC Practice: AC.L1-3.1.1
-
What to look for: Examine authentication middleware, route guards, and session management. Check that all routes or API endpoints that handle sensitive or contract-related data require authentication before processing. Look for middleware patterns that short-circuit unauthenticated requests (e.g.,
if (!session) return redirect('/login'),requireAuth(), or equivalent). Check for any API endpoints that accept POST/PUT/DELETE operations on sensitive resources without first verifying a session or token. Look for public route definitions and ensure none of the protected paths appear there by mistake. -
Pass criteria: Count all routes and API endpoints that handle FCI or sensitive data. All require authentication with no gaps. Auth middleware covers all protected paths. No more than 0 unprotected API endpoints may expose data that should be access-controlled. Report even on pass: "X of Y sensitive routes have authentication middleware." Before evaluating, extract and quote the auth middleware configuration to verify coverage.
-
Fail criteria: Any protected route is accessible without authentication, or API endpoints lack authentication checks. Do NOT pass when middleware covers most routes but excludes specific API paths via a matcher pattern — verify the matcher does not create bypass gaps.
-
Cross-reference: For role-based authorization beyond authentication, see the transaction-control check in this audit.
-
Skip (N/A) when: Never — access control is fundamental to CMMC Level 1.
-
Detail on fail: Identify the specific unprotected route or endpoint. Example:
"GET /api/contracts returns all records without auth check. Middleware in middleware.ts excludes /api/* paths, leaving all API routes unprotected."Keep under 500 characters. -
Remediation: Every route that processes or returns sensitive data must require authentication. In Next.js, use middleware to protect all non-public routes:
// middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' const PUBLIC_PATHS = ['/', '/login', '/signup', '/api/auth'] export function middleware(request: NextRequest) { const { pathname } = request.nextUrl const isPublic = PUBLIC_PATHS.some(p => pathname.startsWith(p)) if (!isPublic && !request.cookies.get('session')) { return NextResponse.redirect(new URL('/login', request.url)) } return NextResponse.next() } export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'] }For API routes, check the session at the top of every handler before processing the request:
// app/api/contracts/route.ts import { getServerSession } from 'next-auth/next' export async function GET(req: Request) { const session = await getServerSession() if (!session) { return Response.json({ error: 'Unauthorized' }, { status: 401 }) } // ... proceed with handler }
External references
- cmmc:2.0 · AC.L1-3.1.1 — Authorized Access Control
- cwe · CWE-306 — Missing Authentication for Critical Function
- owasp:2021 · A01 — Broken Access Control
- nist:rev2 · SP-800-171 3.1.1 — Limit system access to authorized users
Taxons
History
- 2026-04-18·v1.0.0·Initial import from gov-cmmc-level-1·automated