Overly permissive Spring CORS settings

Overly permissive Spring CORS settings

Description

Allowing all origin patterns and credentials in Spring's CorsConfiguration or @CrossOrigin grants overly broad access to credentialed cross-origin requests. When the browser can send credentials, an untrusted site may read sensitive responses. Cookie policies still apply; this setting alone does not disclose cookie values or authentication headers to that site. Spring rejects allowedOrigins("*") combined with allowCredentials(true), but permits allowedOriginPatterns, including originPatterns="*" or setAllowedOriginPatterns(List.of("*")).

Potential impact

  • An untrusted origin may induce the browser to send a request containing authentication cookies.
  • Sensitive API responses may become accessible to external frontends or attacker-controlled pages.
  • A permissive shared CORS configuration may affect multiple Spring API endpoints.

Remediation

  • Restrict origins to an explicit allow-list when using allowCredentials(true).
  • Avoid all-origin patterns such as originPatterns="*" or setAllowedOriginPatterns(List.of("*")).
  • Permit only required trusted origins in production, and apply authentication, authorization and CSRF protection separately.

Examples

These excerpts build a configuration object to connect to the application's CORS handling. Also configure the required methods and headers.

Before

java
import java.util.List;
import org.springframework.web.cors.CorsConfiguration;

public class UnsafeCorsConfig {
    CorsConfiguration build() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOriginPatterns(List.of("*"));
        config.setAllowCredentials(true);
        return config;
    }
}

After

java
import java.util.List;
import org.springframework.web.cors.CorsConfiguration;

public class SafeCorsConfig {
    CorsConfiguration build() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(List.of("https://app.example.com"));
        config.setAllowCredentials(true);
        return config;
    }
}

Explanation:

  • Before: Matches every origin pattern while allowing credentials, opening credentialed cross-origin access too broadly.
  • After: Restricts credentialed access to an explicit trusted origin.

Also restrict origins when using @CrossOrigin(originPatterns = "*", allowCredentials = "true") or originPatterns = {"*"}.

References