# System access limited to authorized users and processes

- **Pattern:** `ab-001549` (`gov-cmmc-level-1.access-control.authorized-access`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001549
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001549)

## 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:

```ts
// 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:

  ```ts
  // 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:

  ```ts
  // 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 AC.L1-3.1.1
- cwe CWE-306
- owasp A01
- nist SP-800-171 3.1.1

Taxons: access-control, regulatory-conformance

HTML version: https://auditbuffet.com/patterns/ab-001549
