Skip to content
Back to skills

Cors Security

ASecurity

Strict CORS: no wildcard with credentials, exact-match origin allowlists, sane preflight cache, minimal exposed headers. Use when generating CORS middleware or framework config, setting CORS headers in API Gateway, CloudFront, or Nginx, or reviewing a cross-origin browser-facing endpoint.

  • 22 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 6, 2026
securityrustgitapidatabasefrontendsecurity

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add ShieldNet-360/secure-vibe --skill cors-security --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cors Security?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cors Security
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/shieldnet-360-cors-security-secure-vibe/badge)](https://www.skillsdirectory.com/skills/shieldnet-360-cors-security-secure-vibe)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cors-security
description: "Strict CORS: no wildcard with credentials, exact-match origin allowlists, sane preflight cache, minimal exposed headers. Use when generating CORS middleware or framework config, setting CORS headers in API Gateway, CloudFront, or Nginx, or reviewing a cross-origin browser-facing endpoint."
---

<!-- Native skill bundle for Claude Code. Generated by `secure-vibe dev regenerate`. -->
<!-- Do not edit by hand; the source of truth is skills/cors-security/SKILL.md. -->

# CORS Security

Strict CORS: no wildcard with credentials, exact-match origin allowlists, sane preflight cache, minimal exposed headers. Use when generating CORS middleware or framework config, setting CORS headers in API Gateway, CloudFront, or Nginx, or reviewing a cross-origin browser-facing endpoint.

## ALWAYS

- For any non-public endpoint, allow origins from an explicit allowlist. `*` is correct only when the resource is intentionally public *and* cross-origin access never carries credentials.
- When a cross-origin request carries credentials — the browser's credentials mode is `include`, meaning cookies, TLS client certificates, or browser-managed HTTP auth — respond with `Access-Control-Allow-Credentials: true` and a **single explicit origin**. On a credentialed request every CORS header loses its wildcard meaning: `*` in `Allow-Origin`, `Allow-Methods`, `Allow-Headers`, or `Expose-Headers` is read as the literal string `"*"` and the browser blocks the response. That is why "just set it to `*` for now" fails in a way that is hard to debug.
- Compare origins by exact match on the **serialized** origin — scheme, host, and port, all three. Never substring, prefix, or suffix matching: `endsWith("example.com")` accepts `https://example.com.evil.com`, and an unescaped `.` in `^https://api.example.com$` accepts `https://apiXexample.com`.
- Include `Vary: Origin` on any response whose headers depend on the request `Origin`, so a shared cache cannot hand one origin's `Access-Control-Allow-Origin` to another.
- Restrict `Access-Control-Allow-Methods` to the methods the endpoint accepts and `Access-Control-Allow-Headers` to the headers it consumes. An app-set `Authorization: Bearer …` header is not "credentials" in the Fetch sense — it is an ordinary header that must be listed in `Allow-Headers` and that triggers a preflight.
- Set a bounded `Access-Control-Max-Age` sized to the deployment; an hour to a day is a conservative production default. Browsers cap this value regardless of what you send, so a very large number buys no extra caching — it only lengthens how long a bad allowlist entry stays cached in clients that already fetched it.
- Source allowed origins only from operator-controlled configuration. Do not derive them from tenant- or user-controlled data unless an addition passes an authenticated, authorized, validated administrative workflow. The risk is not "stored in a database", it is "writable by anyone who can create a row".
- When the request `Origin` is not in the allowlist, omit `Access-Control-Allow-Origin` entirely. Do not fall back to a default trusted origin and do not echo the rejected value — a default-origin fallback silently grants every rejected caller whatever that default origin is allowed to do.

## NEVER

- Reflect the `Origin` header without an allowlist check (`Access-Control-Allow-Origin: <Origin>` for every caller). With credentials this is strictly worse than `*`: the browser refuses `*`, but accepts a reflected origin, so the misconfiguration fails open instead of closed.
- Accept the serialized `null` origin on a credentialed or sensitive endpoint. Every browser serializes an opaque origin to `null` — sandboxed iframes without `allow-same-origin`, `data:` URLs, `file://` documents, some cross-origin redirects. Treat any exception as a documented compatibility decision that passed security review.
- Allow arbitrary subdomains (`.*\.example\.com$`) without accounting for subdomain takeover. Exact matching does not help here: the pattern is implemented correctly and a dangling DNS record hands an attacker a matching origin. Pin specific subdomains; treat a wildcard as a decision tied to subdomain-ownership controls.
- Expose internal headers via `Access-Control-Expose-Headers`. Limit it to the minimal set the frontend genuinely reads.
- Use CORS as authorization. It is a *browser* policy: it does not stop curl, server-to-server calls, or any non-browser client. Authenticate the request.

## KNOWN FALSE POSITIVES

- Intentionally public, non-credentialed resources legitimately use `Access-Control-Allow-Origin: *` — open-data APIs, and static assets served for cross-origin reuse (fonts, images, JS on a CDN). This is the common correct case for `*`.
- A few integrations (Stripe.js, Plaid, Auth0) expect specific CORS headers; read the provider's CORS section before relaxing the baseline.

## Reference files

Read these only when the task calls for them.

- `references/verifying-findings.md`

Files in this skill

  • SKILL.md4.9 KB
  • references/verifying-findings.md3.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.