HIGH cors wildcardspring boot

Cors Wildcard in Spring Boot

How Cors Wildcard Manifests in Spring Boot

CORS wildcard vulnerabilities in Spring Boot applications often stem from overly permissive configuration that allows any origin to access API endpoints. This manifests through several Spring Boot-specific patterns that developers commonly encounter.

The most prevalent manifestation occurs when developers use the wildcard (*) origin in their CORS configuration:

@Configuration
@EnableWebMvc
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                        .allowedOrigins("*")
                        .allowedMethods("*")
                        .allowedHeaders("*");
            }
        };
    }
}

This configuration allows any website to make cross-origin requests to your Spring Boot API, including potentially malicious sites that could exploit authenticated sessions or sensitive data.

Another Spring Boot-specific manifestation occurs through improper use of @CrossOrigin annotations:

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @CrossOrigin(origins = "*")
    @GetMapping
    public List<User> getUsers() {
        return userService.findAll();
    }
}

Developers often apply this pattern across multiple controllers, creating a patchwork of wildcard CORS policies throughout the application.

Spring Boot's auto-configuration can also introduce wildcard CORS when using Spring Security. A common anti-pattern:

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.cors().and()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated());
        return http.build();
    }
}

When combined with a global CORS configuration that allows all origins, this creates a security gap where public endpoints become accessible from any domain, potentially exposing sensitive data or enabling account enumeration attacks.

The impact is particularly severe in Spring Boot applications because of the framework's convention-over-configuration approach. Developers might not realize that adding a single @CrossOrigin annotation with wildcard origins affects the entire application's attack surface, especially when the application is deployed as a public API.

Spring Boot-Specific Detection

Detecting CORS wildcard vulnerabilities in Spring Boot applications requires both static analysis and runtime scanning. Here's how to identify these issues specifically in Spring Boot contexts:

Static Code Analysis

Search your Spring Boot codebase for these patterns:

# Find wildcard CORS configurations
grep -r "allowedOrigins(*)" src/main/java/
grep -r "@CrossOrigin(origins = \"*\")" src/main/java/
grep -r "CorsConfiguration().applyPermitDefaultValues()" src/main/java/

Configuration Files

Check application.properties or application.yml for CORS settings:

# Look for these patterns
spring:
  web:
    cors:
      allowed-origins: "*"
      allowed-methods: "*"
      allowed-headers: "*"

Runtime Scanning with middleBrick

middleBrick's black-box scanning approach is particularly effective for detecting CORS wildcard issues in Spring Boot applications without requiring source code access:

# Scan your Spring Boot API endpoint
middlebrick scan https://yourapi.example.com/api/users

middleBrick tests CORS policies by making cross-origin requests from multiple domains and analyzing the Access-Control-Allow-Origin headers returned. For Spring Boot applications specifically, it checks:

  • Whether wildcard origins are accepted
  • If credentialed requests are allowed with wildcard origins (a critical violation)
  • Whether preflight requests are handled securely
  • If specific Spring Boot endpoints have overly permissive CORS policies
  • The scanner provides a security score and detailed findings, including whether your Spring Boot API is vulnerable to cross-origin attacks.

    Spring Boot Actuator Integration

    If your Spring Boot application uses Actuator endpoints, check their CORS configuration separately:

    management.endpoints.web.cors.allowed-origins=*
    

    Exposed Actuator endpoints with wildcard CORS can reveal sensitive application metrics and configuration details to attackers.

Spring Boot-Specific Remediation

Remediating CORS wildcard vulnerabilities in Spring Boot requires a security-first approach with specific configuration patterns. Here are Spring Boot-native solutions:

Whitelist Specific Origins

@Configuration
@EnableWebMvc
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                        .allowedOrigins("https://yourdomain.com", "https://yourapp.com")
                        .allowedMethods("GET", "POST", "PUT", "DELETE")
                        .allowedHeaders("Content-Type", "Authorization")
                        .allowCredentials(true); // Only if needed
            }
        };
    }
}

Environment-Specific Configuration

Use Spring Boot's profile system for different CORS policies in dev vs production:

@Configuration
@Profile("production")
public class ProductionCorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                        .allowedOrigins(getAllowedOrigins())
                        .allowedMethods("GET", "POST")
                        .maxAge(3600);
            }
        };
    }

    private String[] getAllowedOrigins() {
        return StringUtils.commaDelimitedListToStringArray(
            env.getProperty("cors.allowed.origins", "https://yourdomain.com")
        );
    }
}

Spring Security Integration

Configure CORS securely within Spring Security:

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        CorsConfigurationSource corsConfigSource = new CorsConfigurationSource() {
            @Override
            public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
                CorsConfiguration config = new CorsConfiguration();
                config.setAllowedOrigins(Arrays.asList("https://yourdomain.com"));
                config.setAllowedMethods(Arrays.asList("GET", "POST"));
                config.setAllowedHeaders(Arrays.asList("Content-Type", "Authorization"));
                config.setAllowCredentials(true);
                return config;
            }
        };

        http.cors(cors -> cors.configurationSource(corsConfigSource))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/private/**").hasRole("USER")
                .anyRequest().authenticated());
        return http.build();
    }
}

Controller-Level Security

Apply specific CORS policies at the controller level:

@RestController
@RequestMapping("/api/users")
@CrossOrigin(
    origins = "https://yourapp.com",
    allowedHeaders = {"Content-Type", "Authorization"},
    methods = {RequestMethod.GET, RequestMethod.POST}
)
public class UserController {
    
    @GetMapping
    public ResponseEntity<List<User>> getUsers() {
        return ResponseEntity.ok(userService.findAll());
    }
}

Testing Your Configuration

After remediation, verify your CORS configuration:

@SpringBootTest
@AutoConfigureMockMvc
public class CorsSecurityTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @Test
    public void testCorsPolicy() throws Exception {
        mockMvc.perform(get("/api/users")
                .header("Origin", "https://yourapp.com"))
                .andDo(print())
                .andExpect(header().string("Access-Control-Allow-Origin", "https://yourapp.com"));
    }
}

For comprehensive validation, use middleBrick's continuous monitoring in the Pro plan to ensure your CORS policies remain secure as your Spring Boot application evolves.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Why is allowing all origins (*) with credentials considered a critical vulnerability?
When a Spring Boot application allows all origins (*) while also allowing credentials (cookies, authorization headers), browsers will reject the response entirely for security reasons. However, if credentials are not required but sensitive data is returned, any website can make requests to your API and read the responses, enabling data exfiltration attacks. middleBrick specifically flags this combination as critical because it completely undermines the purpose of authentication and authorization.
Can I use environment variables to manage CORS origins in Spring Boot?
Yes, Spring Boot's externalized configuration makes this straightforward. In application.yml, you can use: cors: allowed-origins: ${CORS_ALLOWED_ORIGINS:https://default.com}. This allows you to set the CORS origins via environment variables in production while maintaining a default for development. middleBrick's scanning will verify that your runtime configuration matches your security requirements regardless of how it's configured.