This is an automated email from the ASF dual-hosted git repository.
epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-mcp.git
The following commit(s) were added to refs/heads/main by this push:
new 8eff997 fix(security): replace permissive CORS wildcard with explicit
allowlist (#121)
8eff997 is described below
commit 8eff997e4038565a9be10647225056322d9a16d4
Author: Aditya Parikh <[email protected]>
AuthorDate: Fri May 8 17:01:09 2026 -0400
fix(security): replace permissive CORS wildcard with explicit allowlist
(#121)
The HTTP CORS configuration used setAllowedOriginPatterns("*") with
allowCredentials=true, which is Spring's escape hatch around the
browser rule that wildcards can't be used with credentials (MDN CORS
spec). Replace with the strict setAllowedOrigins API and a configurable
allowlist that defaults to the MCP Inspector's local proxy port.
Methods and headers also tightened to the explicit set used by the
Streamable HTTP transport per the MCP specification, replacing
"*" wildcards.
Operators add additional origins via the MCP_CORS_ALLOWED_ORIGINS env
var or the mcp.cors.allowed-origins property.
Refs:
- MDN CORS — Credentialed requests and wildcards
- CWE-942: Permissive Cross-domain Policy with Untrusted Domains
- OWASP HTML5 Security Cheat Sheet (CORS)
Signed-off-by: adityamparikh <[email protected]>
Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
Co-authored-by: Eric Pugh <[email protected]>
---
.../server/security/HttpSecurityConfiguration.java | 19 ++++++++++++++++---
src/main/resources/application-http.properties | 4 ++++
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git
a/src/main/java/org/apache/solr/mcp/server/security/HttpSecurityConfiguration.java
b/src/main/java/org/apache/solr/mcp/server/security/HttpSecurityConfiguration.java
index 61f5663..d42be30 100644
---
a/src/main/java/org/apache/solr/mcp/server/security/HttpSecurityConfiguration.java
+++
b/src/main/java/org/apache/solr/mcp/server/security/HttpSecurityConfiguration.java
@@ -39,6 +39,9 @@ class HttpSecurityConfiguration {
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri:}")
private String issuerUrl;
+ @Value("${mcp.cors.allowed-origins}")
+ private List<String> allowedOrigins;
+
@Bean
@ConditionalOnProperty(name = "http.security.enabled", havingValue =
"true", matchIfMissing = true)
SecurityFilterChain securityFilterChain(HttpSecurity http) throws
Exception {
@@ -80,9 +83,19 @@ class HttpSecurityConfiguration {
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
- configuration.setAllowedOriginPatterns(List.of("*"));
- configuration.setAllowedMethods(List.of("*"));
- configuration.setAllowedHeaders(List.of("*"));
+ // Use the strict setAllowedOrigins API (not
setAllowedOriginPatterns) so the
+ // browser-spec rule that wildcards cannot be combined with
credentials is
+ // enforced.
+ // Origins are configurable via the mcp.cors.allowed-origins
property
+ // (env: MCP_CORS_ALLOWED_ORIGINS) and default to the MCP
Inspector's local
+ // proxy.
+ configuration.setAllowedOrigins(allowedOrigins);
+ // Only the HTTP methods used by the MCP Streamable HTTP
transport.
+ configuration.setAllowedMethods(List.of("GET", "POST",
"DELETE", "OPTIONS"));
+ // Only the headers the MCP specification requires for the
Streamable HTTP
+ // transport.
+ configuration.setAllowedHeaders(
+ List.of("Authorization", "Content-Type",
"Mcp-Session-Id", "MCP-Protocol-Version", "Last-Event-ID"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new
UrlBasedCorsConfigurationSource();
diff --git a/src/main/resources/application-http.properties
b/src/main/resources/application-http.properties
index 1364348..6a613b5 100644
--- a/src/main/resources/application-http.properties
+++ b/src/main/resources/application-http.properties
@@ -28,6 +28,10 @@
spring.security.oauth2.resourceserver.jwt.issuer-uri=${OAUTH2_ISSUER_URI:https:/
# in any environment reachable from the network is unsafe; the MCP
Authorization
# specification requires HTTP-based MCP servers to authenticate.
http.security.enabled=${HTTP_SECURITY_ENABLED:true}
+# Comma-separated list of allowed CORS origins for the MCP HTTP endpoint.
+# Defaults to MCP Inspector's local proxy. Add additional origins
(browser-based
+# MCP clients, internal dashboards) as needed. Do NOT use "*" with credentials.
+mcp.cors.allowed-origins=${MCP_CORS_ALLOWED_ORIGINS:http://localhost:6274,http://127.0.0.1:6274}
# observability
management.endpoints.web.exposure.include=health,sbom,metrics,info,loggers,prometheus
# Enable @Observed annotation support for custom spans