rules:
  - id: auth.cors.null-origin
    languages:
      - javascript
      - typescript
    severity: ERROR
    message: |
      CORS is configured to allow the literal origin `'null'`. Sandboxed
      iframes, documents loaded from `file://`, and certain cross-origin
      redirects send `Origin: null`. Adding the string `'null'` to your
      CORS policy therefore grants cross-origin access to ANY such context
      (including an attacker's sandboxed iframe), which defeats the
      same-origin policy. Combined with credentials this becomes a
      CSRF / data-exfiltration primitive.

      The `'null'` origin is not a safe sentinel and cannot be trusted:
      it is not bound to any host. Remove it from the allowlist entirely.

      Use an explicit allowlist of real, trusted origins instead:
       - `cors({ origin: 'https://app.example.com', credentials: true })`
       - `cors({ origin: ['https://app.example.com', 'https://admin.example.com'] })`

      Never set `Access-Control-Allow-Origin` to the string `'null'` and
      never include `'null'` in a CORS origin allowlist.
    pattern-either:
      # Manual header write: ACAO set to the literal string "null".
      - pattern: $RES.setHeader("Access-Control-Allow-Origin", "null")
      - pattern: $RES.header("Access-Control-Allow-Origin", "null")
      - pattern: $RES.set("Access-Control-Allow-Origin", "null")
      # express cors() middleware: origin is the literal string "null".
      - pattern: 'cors({ ..., origin: "null", ... })'
      # express cors() middleware: allowlist array literal that contains "null".
      - pattern: 'cors({ ..., origin: [..., "null", ...], ... })'
      # An allowlist array variable containing "null" that is then used as the
      # cors() origin (handles the indirected `const allowed = [..., 'null']`).
      - patterns:
          - pattern: 'cors({ ..., origin: $ALLOWED, ... })'
          - pattern-inside: |
              $ALLOWED = [..., "null", ...];
              ...
    metadata:
      oauthlint-rule-id: AUTH-CORS-003
      oauthlint-doc-url: https://oauthlint.dev/rules/cors-null-origin
      category: security
      cwe: CWE-942
      owasp: API8:2023
      llm-prevalence: MEDIUM
      technology:
        - cors
        - express
      references:
        - https://portswigger.net/web-security/cors
        - https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS
