# External connections verified and controlled

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

## Why it matters

CMMC 2.0 AC.L1-3.1.20 (NIST 800-171r2 3.1.20) requires that external connections are verified and controlled. A wildcard CORS origin (`Access-Control-Allow-Origin: *`) allows any website to make credentialed cross-origin requests to your API, exposing session-authenticated FCI endpoints to drive-by exfiltration via CSRF-style attacks. The absence of a Content Security Policy leaves the door open for injected third-party scripts to exfiltrate data from the page. OWASP A05 (Security Misconfiguration) names both as common high-severity misconfigurations. CWE-942 (Overly Permissive Cross-domain Whitelist) applies directly.

## Severity rationale

Medium because exploiting wildcard CORS requires a victim to visit an attacker-controlled page while authenticated, adding a social-engineering step before data is exposed.

## Remediation

Replace wildcard CORS with explicit origin allowlists and add a restrictive CSP in `next.config.ts`. Both controls are required — AC.L1-3.1.20 is not satisfied by one alone:

```ts
// next.config.ts
const nextConfig = {
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          { key: 'Access-Control-Allow-Origin', value: process.env.ALLOWED_ORIGIN ?? 'https://yourdomain.com' },
          { key: 'Access-Control-Allow-Methods', value: 'GET,POST,PUT,DELETE,OPTIONS' },
          { key: 'Access-Control-Allow-Headers', value: 'Content-Type, Authorization' },
        ],
      },
      {
        source: '/:path*',
        headers: [
          { key: 'Content-Security-Policy', value: "default-src 'self'; script-src 'self'; connect-src 'self' https://api.trusted-service.com" },
        ],
      },
    ]
  },
}
export default nextConfig
```

Set `ALLOWED_ORIGIN` in your production environment — never leave it unset or defaulting to `*`.

## Detection

- **ID:** `external-connections`
- **Severity:** `medium`
- **CMMC Practice:** AC.L1-3.1.20
- **What to look for:** Examine CORS configuration, Content Security Policy (CSP) headers, allowed origins lists, and outbound API call patterns. Check `next.config.js` or equivalent for CORS settings. Look for wildcard `*` in CORS origin configuration in production. Check CSP headers — do they restrict which external scripts, images, and styles can be loaded? Review any third-party integrations (payment processors, analytics, external APIs) and whether they are documented or controlled. Look for `fetch()` or `axios` calls to external services and whether the target domains are configured rather than hardcoded.
- **Pass criteria:** List all CORS origins and CSP directives configured in the project. CORS is configured with specific allowed origins (not a wildcard `*`) in production. At least 1 CSP directive is present. Third-party connections are to known/trusted services only. Report even on pass: "CORS allows X specific origins; CSP has Y directives."
- **Fail criteria:** CORS configured with `Access-Control-Allow-Origin: *` in production. No CSP headers to restrict external resource loading. Do NOT pass when CORS restricts origins but CSP is entirely absent — both protections are required.
- **Skip (N/A) when:** Static site with no API endpoints and no external connections.
- **Detail on fail:** Specify the misconfiguration. Example: `"CORS configured with origin: '*' in next.config.ts — any domain can make authenticated cross-origin requests. No CSP header found in security header configuration."` Keep under 500 characters.
- **Remediation:** Configure CORS with explicit allowed origins and add a CSP:

  ```ts
  // next.config.ts
  const nextConfig = {
    async headers() {
      return [
        {
          source: '/api/:path*',
          headers: [
            {
              key: 'Access-Control-Allow-Origin',
              value: process.env.ALLOWED_ORIGIN ?? 'https://yourdomain.com'
            },
            { key: 'Access-Control-Allow-Methods', value: 'GET,POST,PUT,DELETE,OPTIONS' },
            { key: 'Access-Control-Allow-Headers', value: 'Content-Type, Authorization' }
          ]
        },
        {
          source: '/:path*',
          headers: [
            {
              key: 'Content-Security-Policy',
              value: "default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self' https://api.trusted-service.com"
            }
          ]
        }
      ]
    }
  }
  export default nextConfig
  ```

## External references

- cmmc AC.L1-3.1.20
- cwe CWE-942
- owasp A05
- nist SP-800-171 3.1.20

Taxons: access-control, regulatory-conformance

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