CORS, CSRF and Web Security Questions
What is CSRF and when can you disable CSRF protection?
Cross-Site Request Forgery tricks a logged-in user's browser into sending a request (e.g. "transfer money") to your site; the browser attaches the session cookie automatically. Spring Security blocks it by requiring a CSRF token on POST/PUT/PATCH/DELETE. You can disable it for a stateless API that authenticates with a Bearer header and uses no cookies, because browsers do not add that header automatically. Keep it on whenever authentication travels in cookies.
What is CORS and how do you configure it in Spring Security?
http.cors(Customizer.withDefaults()); // uses the bean below
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration c = new CorsConfiguration();
c.setAllowedOrigins(List.of("https://shopease.in", "http://localhost:5173"));
c.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
c.setAllowedHeaders(List.of("Authorization", "Content-Type"));
c.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", c);
return source;
}CORS is a browser rule that blocks JavaScript from reading responses from another origin unless the server allows it. Configuring it in the security chain matters because the browser's preflight OPTIONS request has no credentials; without http.cors() it would get a 401. CORS is not an authentication mechanism.
How do you set up CSRF for a React SPA that uses session cookies?
http.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()));Spring writes the token into an XSRF-TOKEN cookie that JavaScript can read; the SPA (axios does this automatically) sends it back in the X-XSRF-TOKEN header. An attacker's site cannot read your cookie, so it cannot forge the header.
Where should a SPA store the JWT: localStorage or a cookie?
| localStorage | HttpOnly Secure SameSite cookie | |
|---|---|---|
| XSS | any injected script can steal the token | JavaScript cannot read it |
| CSRF | not affected (header is added manually) | need SameSite + CSRF token |
| Effort | simple | needs same-site setup and CORS with credentials |
A common, safer pattern: short-lived access token in memory, refresh token in an HttpOnly Secure cookie.
Which security headers does Spring Security add by default?
X-Content-Type-Options: nosniffX-Frame-Options: DENY(clickjacking protection)Cache-Control: no-cache, no-store, max-age=0, must-revalidateStrict-Transport-Security(HSTS) on HTTPS requests- You can add
Content-Security-Policywithheaders(h -> h.contentSecurityPolicy(c -> c.policyDirectives("default-src 'self'"))).