Every developer has hit a CORS error in the browser console at least once, and almost every developer's first instinct is the same Stack Overflow answer: add Access-Control-Allow-Origin: * and move on. That header does exactly what it says — it tells browsers that literally any website is allowed to read responses from your API — and in a lot of cases that's a much bigger door to open than the error message made it feel like.
What CORS is actually protecting
The browser's same-origin policy normally stops JavaScript running on evil.example from reading a response returned by yourapp.com, even if the user's browser happily sends the request (with their cookies attached). CORS headers are how yourapp.com explicitly opts certain other origins into being allowed to read that response. It's an opt-in relaxation of a default protection — not a security feature to configure defensively, but a permission slip you're handing out.
Where the wildcard becomes a real problem
For a public, unauthenticated API — a weather endpoint, a public dataset — a wildcard origin is usually fine, because there's no user-specific session or secret data being returned. The risk shows up when that same wildcard is applied to authenticated endpoints. Combined with Access-Control-Allow-Credentials: true (which some frameworks allow you to pair with a wildcard, and some correctly refuse to), a malicious site can make a request that includes the victim's session cookie and read back their private data, because the browser was told any origin is allowed to.
# Fine for a public, unauthenticated endpoint
Access-Control-Allow-Origin: *
# Risky if this endpoint returns anything user-specific or session-gated
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
The fix is almost always an explicit allow-list
Most frameworks, including Django (via django-cors-headers), support an explicit list of allowed origins: CORS_ALLOWED_ORIGINS = ["https://yourapp.com", "https://app.yourapp.com"]. This keeps the same convenience for your own frontend while refusing the request outright for any origin you didn't name. It's one config change, and it's easy to get right once you know to look for the wildcard on anything that isn't fully public data.
Takeaway
A CORS error in development almost always means the browser is doing its job. The fix is naming the origins you actually trust, not removing the check entirely with a wildcard that's easy to add under deadline pressure and easy to forget to narrow later.