BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Security

Spring

CORS and CSRF protection

CORS decides which web pages from other origins may call your API from a browser.

Learn these first

At a glance

Mental model

CORS is the guest list at the door of your building: which other buildings may send visitors.

What happens, in order
  1. 1The browser enforces the same-origin policyFor a call to another origin it first sends an OPTIONS preflight; the API answers with Access-Control-Allow-Origin, -Methods and -Headers if allowed. The browser then performs or blocks the real request.
  2. 2In Spring configure it once: a CorsConfigurationSource bean, http.cors(...), or @CrossOrigin on a controllerList explicit origins; allowCredentials(true) cannot be combined with the wildcard *.
  3. 3CSRF: when authentication rides on cookies, any site can make the browser send the cookieThe server requires an extra token (a cookie XSRF-TOKEN copied into the header X-XSRF-TOKEN by the front end) that a foreign site cannot read.
  4. 4Token-based APIs that use a Bearer header (not a cookie) are not vulnerable to CSRF, which is why stateless JWT APIs typically disable it
Remember
Watch out
Wildcard origins with credentialsReflecting the Origin header blindlyDisabling CSRF for a cookie-based appUsing GET for changes
Example (highlighted lines explain it)
@BeanCorsConfigurationSource corsConfigurationSource() {    CorsConfiguration config = new CorsConfiguration();    config.setAllowedOrigins(List.of("https://app.acme.com"));    config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));    config.setAllowedHeaders(List.of("Authorization", "Content-Type"));    config.setAllowCredentials(true);    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();    source.registerCorsConfiguration("/api/**", config);    return source;}
  1. line 2 uses CorsConfiguration, the core of CORS and CSRF protection
  2. line 3 uses CorsConfiguration, the core of CORS and CSRF protection
  3. line 8 uses UrlBasedCorsConfigurationSource, the core of CORS and CSRF protection
  4. line 9 uses CorsConfiguration, the core of CORS and CSRF protection
Read the full explanation (about 2 min)

CORS decides which web pages from other origins may call your API from a browser. CSRF protection stops a malicious site from making the browser send an authenticated request on the user behalf. They are often confused but solve different problems.

A mental model

CORS is the guest list at the door of your building: which other buildings may send visitors. CSRF protection is checking a secret handshake, because a forger could otherwise trick a legitimate resident into signing something.

How it works

The browser enforces the same-origin policy. For a call to another origin it first sends an OPTIONS preflight; the API answers with Access-Control-Allow-Origin, -Methods and -Headers if allowed. The browser then performs or blocks the real request.

In Spring configure it once: a CorsConfigurationSource bean, http.cors(...), or @CrossOrigin on a controller. List explicit origins; allowCredentials(true) cannot be combined with the wildcard *.

CSRF: when authentication rides on cookies, any site can make the browser send the cookie. The server requires an extra token (a cookie XSRF-TOKEN copied into the header X-XSRF-TOKEN by the front end) that a foreign site cannot read.

Token-based APIs that use a Bearer header (not a cookie) are not vulnerable to CSRF, which is why stateless JWT APIs typically disable it.

Going deeper

CORS is a browser rule, not authentication. curl and servers ignore it. A permissive CORS setting does not expose more data to attackers but lets other websites read responses with the visitor credentials, which is the danger.

Never reflect any Origin header back with credentials allowed, and never allow null origin; both defeat the check.

Cookies should use SameSite=Lax or Strict, HttpOnly and Secure, which blocks most CSRF on its own. State-changing operations must never use GET.

Under the hood

CorsFilter runs early in the chain, matches the request origin against the configuration and short-circuits preflights with the allow headers. CsrfFilter loads the expected token from the repository (session or cookie) for each state-changing method and compares it with the one sent in the header or form field, using a constant-time comparison.

Common mistakes

  • Wildcard origins with credentials.
  • Reflecting the Origin header blindly.
  • Disabling CSRF for a cookie-based app.
  • Using GET for changes.

How Unravel recognises it

When you paste code, Unravel looks for these signs of cors and csrf protection. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is CORS and CSRF protection?

CORS decides which web pages from other origins may call your API from a browser. CSRF protection stops a malicious site from making the browser send an authenticated request on the user behalf. They are often confused but solve different problems.

What are the most common mistakes with CORS and CSRF protection?

Wildcard origins with credentials. Reflecting the Origin header blindly. Disabling CSRF for a cookie-based app. Using GET for changes.

How can I see CORS and CSRF protection in real code?

Paste your own Java into Unravel and it will point out where cors and csrf protection appears, explain how it works at the detail level you choose, and draw the flow of the code around it.