← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

CORS

networking PHP 5.0+ Intermediate

Also Known As

Cross-Origin Resource Sharing CORS policy

TL;DR

Cross-Origin Resource Sharing — the browser mechanism that controls which cross-origin requests are permitted, using HTTP headers negotiated between client and server.

Explanation

Browsers enforce the same-origin policy by default, blocking cross-origin AJAX requests. CORS relaxes this via server-sent headers. Simple requests (GET, POST with safe content types) are sent directly; the browser checks the response headers. Preflighted requests (PUT, DELETE, custom headers) first send an OPTIONS request to check permissions. Misconfigured CORS is one of the most common web security vulnerabilities.

Diagram

sequenceDiagram
    participant B as Browser
    participant S as Server
    Note over B,S: Simple Request - GET/POST safe content-type
    B->>S: GET /api/data with Origin header
    S-->>B: 200 OK with Access-Control-Allow-Origin
    Note over B,S: Preflighted Request - PUT or custom headers
    B->>S: OPTIONS /api/data preflight
    S-->>B: 204 with Access-Control-Allow-Methods: PUT
    B->>S: PUT /api/data actual request
    S-->>B: 200 OK

Watch Out

Reflecting the incoming Origin header without validation is equivalent to a wildcard — any origin is allowed, defeating CORS entirely and enabling cross-origin reads of authenticated responses.

Common Misconception

CORS is a security feature that protects the server — it actually protects the user's browser; a server-side attacker is unaffected by CORS.

Why It Matters

Permissive CORS configuration turns the browser's same-origin policy off, allowing malicious sites to make authenticated API calls on behalf of the victim.

Common Mistakes

  • Reflecting the incoming Origin header as Access-Control-Allow-Origin without validating against an allowlist.
  • Setting Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true — browsers block this combination.
  • Allowlisting by substring match — evil-yoursite.com passes a check for yoursite.com.
  • Not setting Vary: Origin when responses differ by origin — CDNs serve the wrong cached response.

Avoid When

  • Do not set Access-Control-Allow-Origin: * on APIs that use cookies or session-based authentication — credentials are never sent with wildcard origins but the misconfiguration signals a broken policy.
  • Avoid configuring CORS at the application layer if a gateway or CDN already handles it — duplicate headers break the browser negotiation.

When To Use

  • Set Access-Control-Allow-Origin to a specific allowlist of trusted origins — never reflect the incoming Origin header directly.
  • Use credentials: true (cookies/auth headers) only when the origin is explicitly trusted and listed — never combine it with a wildcard origin.
  • Validate preflight OPTIONS requests and return correct Access-Control-Allow-Methods and Headers to avoid blocking legitimate cross-origin requests.

Code Examples

💡 Note
The bad example copies any Origin straight into the response header — an attacker's domain receives authenticated API responses. The fix checks the origin against an explicit allowlist before echoing it.
✗ Vulnerable
// Reflecting any Origin — security bypass:
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
header('Access-Control-Allow-Origin: ' . $origin); // Any origin allowed!
header('Access-Control-Allow-Credentials: true');
// Attacker's evil.com can now make authenticated requests
✓ Fixed
// Validate against allowlist:
$allowed = ['https://app.example.com', 'https://admin.example.com'];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowed, true)) {
    header('Access-Control-Allow-Origin: ' . $origin);
    header('Access-Control-Allow-Credentials: true');
    header('Vary: Origin');
}

Added 15 Mar 2026
Edited 31 Mar 2026
Views 24
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Amazonbot 6 Perplexity 5 Google 4 ChatGPT 3 Ahrefs 2
crawler 19 crawler_json 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Never set Access-Control-Allow-Origin to * for authenticated endpoints; always validate the Origin header against an allowlist and return the specific origin, not the wildcard
📦 Applies To
PHP 5.0+ web api
🔗 Prerequisites
🔍 Detection Hints
Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true; dynamic Origin reflection without validation
Auto-detectable: ✓ Yes semgrep owasp-zap burpsuite
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update
CWE-942

✓ schema.org compliant