For web applications, Cross-Origin Resource Sharing (CORS) is an essential security component. It specifies how one domain's resources can be accessed by another. Serious security threats, including data theft, unauthorized access to APIs, and potentially account compromise, can arise from improperly setup CORS. This post will go over the recommended practices for securing your applications, typical setup errors, and how to properly set up CORS in ASP.NET Core APIs.

Why CORS Matters?
Modern browsers enforce the Same-Origin Policy, which restricts web pages from making requests to a different domain, protocol, or port. CORS provides a controlled way for servers to relax this restriction and specify which origins are allowed to access resources.

For example

  • Allowed: https://example.com can call https://api.example.com.
  • Blocked: https://attacker.com cannot call https://api.example.com unless CORS allows it.

When developers configure CORS too loosely (e.g.), attackers may exploit the API from malicious websites.

Common CORS Misconfigurations

Using AllowAnyOrigin() with Authentication
builder.Services.AddCors(options =>
{
    options.AddPolicy("OpenPolicy", policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});


This allows any site to call your API, even if cookies, tokens, or credentials are included.

Risk: Attackers can perform Cross-Site Request Forgery (CSRF) or steal user data.

Allowing Credentials with Wildcards
policy.AllowAnyOrigin()
      .AllowCredentials();


This is invalid in ASP.NET Core, but if forced, it opens a massive security hole. Credentials (cookies, Authorization headers) should only be sent to trusted origins.

Overly Broad Allowed Origins
policy.WithOrigins("https://*.example.com");

Wildcard subdomains may unintentionally allow untrusted or user-controlled domains (e.g., evil.example.com).

Forgetting to Restrict Methods/Headers
policy.WithOrigins("https://trusted.com")
      .AllowAnyHeader()
      .AllowAnyMethod();

Over-permissive headers and methods allow attackers to abuse API endpoints in unexpected ways.

Correctly Configuring CORS in ASP.NET Core

Step 1: Define Trusted Origins

Only allow specific, trusted origins that require access to your API.
builder.Services.AddCors(options =>
{
    options.AddPolicy("SecurePolicy", policy =>
    {
        policy.WithOrigins("https://app.example.com", "https://admin.example.com")
              .WithMethods("GET", "POST")        // Only required methods
              .WithHeaders("Content-Type", "Authorization"); // Only necessary headers
    });
});

Step 2: Apply CORS Policy
Apply globally or per controller.

Global Middleware
var app = builder.Build();

app.UseCors("SecurePolicy");

Per Controller
[EnableCors("SecurePolicy")]
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
    // Endpoints here
}

Step 3: Handle Credentials Carefully
If your API needs cookies or tokens with cross-origin requests:
policy.WithOrigins("https://app.example.com")
      .AllowCredentials()
      .WithHeaders("Content-Type", "Authorization");


Always restrict origins to exact, trusted domains.
Best Practices to Prevent CORS Misconfigurations

  • Never use AllowAnyOrigin() in production APIs.
  • Avoid wildcards in allowed origins, headers, or methods.
  • Restrict credentials: Only allow them for trusted, exact origins.
  • Log and monitor preflight requests (OPTIONS) to detect misuse.
  • Use environment-based policies (e.g., open CORS in dev, strict in production).

    if (app.Environment.IsDevelopment())
    {
        app.UseCors("DevPolicy"); // More permissive
    }
    else
    {
        app.UseCors("SecurePolicy"); // Strict
    }

    Test your CORS configuration with tools like curl or browser dev tools to confirm restrictions work as intended.

Example: Secure CORS Setup for an API
builder.Services.AddCors(options =>
{
    options.AddPolicy("ApiCorsPolicy", policy =>
    {
        policy.WithOrigins("https://client.example.com")
              .WithMethods("GET", "POST")
              .WithHeaders("Authorization", "Content-Type")
              .AllowCredentials();
    });
});

var app = builder.Build();

app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();

app.UseCors("ApiCorsPolicy");

app.MapControllers();


Conclusion
Although CORS permits valid cross-domain queries, a misconfiguration can leave your ASP.NET Core API vulnerable to serious threats. You can make sure your API is secure and functional by limiting origins, headers, and methods to what is required and staying away from risky patterns like AllowAnyOrigin().

HostForLIFE ASP.NET Core 9.0 Hosting

European Best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.