Introduction
A crafted HTTP request to a Spring Cloud Config Server backed by Google Secrets Manager can silently return secrets from GCP projects the caller was never intended to access. For any organization relying on Spring Cloud Config to distribute application secrets across microservices, CVE-2026-40981 represents a direct path from an unauthenticated network position to reading credentials stored in arbitrary GCP projects, limited only by the breadth of the Config Server's own service account permissions.
Spring Cloud Config is a central component in the Spring ecosystem for externalized configuration management. It is widely deployed in Java enterprise environments and cloud native architectures to serve configuration properties, including secrets, to distributed applications at scale.
Technical Information
Root Cause: Unvalidated Client Controlled Project ID
The vulnerability exists in the GoogleSecretManagerV1AccessStrategy class, which handles secret retrieval from GCP Secret Manager on behalf of Config Server clients. Prior to the fix, when a Config Client sent an X-Project-ID HTTP header to the Config Server, the getProjectId() method accepted the header value without any validation or authorization check:
// OLD (vulnerable) — blindly accepted header result = configProvider.getValue(HttpHeaderGoogleConfigProvider.PROJECT_ID_HEADER, true);
This is a textbook instance of CWE-639: Authorization Bypass Through User Controlled Key. The system's authorization functionality did not prevent one client from gaining access to another project's secrets by simply modifying the key value (the project ID) in the request. The authorization process failed to verify whether the requesting client had any entitlement to the specified project's secrets.
CVSS Breakdown
The CVSS v3.1 vector is AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N, scoring 7.5 (High). Breaking this down:
- Attack Vector: Network and Privileges Required: None confirm that any unauthenticated network client can attempt exploitation.
- Attack Complexity: Low means no special conditions or race windows are needed.
- Confidentiality Impact: High reflects the direct exposure of sensitive secrets.
- Integrity and Availability: None since the flaw is read only.
Attack Flow
An attacker exploiting this vulnerability would follow these steps:
- Identify a Spring Cloud Config Server instance that uses Google Secrets Manager as its backend. This can sometimes be inferred from error messages, response patterns, or knowledge of the target's infrastructure.
- Craft an HTTP request to the Config Server that includes an
X-Project-IDheader set to the GCP project ID of a different project. The attacker would need to know or guess valid GCP project IDs, but these are often predictable (e.g.,company-production,company-staging). - If the Config Server's service account has IAM permissions on the targeted GCP project (a common scenario in organizations that share service accounts or grant broad cross project access), the server retrieves and returns secrets from that unintended project.
- The attacker receives secrets they were never authorized to access, potentially including database credentials, API keys, encryption keys, and other sensitive configuration data.
The blast radius is bounded by the IAM permissions of the Config Server's service account. In organizations with permissive cross project IAM policies, a single Config Server could expose secrets across dozens of GCP projects.
Patch Information
The Spring team addressed CVE-2026-40981 in commit 4e93ce5, authored by Ryan Baxter on April 21, 2026, and merged into both the v5.0.3 and v4.3.3 releases on May 6, 2026. The commit is titled "Add allowed-project-ids property" and totals 391 additions and 35 deletions across seven files.
What the Patch Changes
The fix introduces a new class, GcpProjectResolutionSupport, which encapsulates and secures all project ID resolution logic. This class replaces the old inline resolution code in GoogleSecretManagerV1AccessStrategy.
The new resolution follows a strict waterfall:
X-Project-IDheader: If the client supplies this header andtoken-mandatoryistrue(the new default), the value is accepted because access is still gated by the downstreamcheckRemotePermissions()IAM check. Iftoken-mandatoryisfalse, the header value is checked against a newallowed-project-idsallow list. If the list is empty, all client supplied project IDs are rejected.- GCE Metadata endpoint: If no header is present, the server queries the metadata server. The allow list does not apply here since this path cannot be steered by the client.
project-idproperty fallback: A new server admin only config property serves as a last resort (e.g., for local development). This is also not subject to the allow list.- If nothing resolves:
getSecrets()returns an empty list andcheckRemotePermissions()returnsfalse, so no Secret Manager backed property sources are contributed for that request.
The key code change in GoogleSecretManagerV1AccessStrategy:
// NEW (fixed) — delegates to allow-list-aware resolver if (projectResolutionSupport != null) { String project = projectResolutionSupport.resolve(configProvider, rest); if (project != null) { return project; } } return null; // no GSM data for this request
The allow list enforcement inside GcpProjectResolutionSupport.resolve() for the token-mandatory=false case:
private boolean isProjectAllowed(String projectId) { List<String> allowed = properties.getAllowedProjectIds(); if (allowed == null || allowed.isEmpty()) { return false; // empty list = reject all client-supplied IDs } for (String candidate : allowed) { if (candidate != null && projectId.equals(candidate.trim())) { return true; } } return false; }
New Configuration Properties
Two new properties were added to GoogleSecretManagerEnvironmentProperties:
allowed-project-ids(List<String>, default empty): The explicit allow list for client suppliedX-Project-IDvalues whentoken-mandatory=false.project-id(String): A server side fallback project when the metadata server is unreachable.
The old constructors of GoogleSecretManagerV1AccessStrategy that did not accept GcpProjectResolutionSupport have been marked @Deprecated(forRemoval = true), and the factory class GoogleSecretManagerAccessStrategyFactory now injects GcpProjectResolutionSupport into every strategy it creates.
The commit includes comprehensive unit tests in GcpProjectResolutionSupportTests covering five scenarios: header denied when the allow list is empty, header allowed when in the list, header allowed when token-mandatory=true regardless of list, metadata fallback, configured project-id fallback, and null when no resolution is possible.
Immediate Containment
If you cannot upgrade immediately, set the following property to require client token verification, which blocks unauthorized cross project access:
spring.cloud.config.server.gcp-secret-manager.token-mandatory=true
Fixed Releases (Published May 6, 2026)
| Branch | Fixed Version | Availability |
|---|---|---|
| 5.0.x | 5.0.3 | OSS |
| 4.3.x | 4.3.3 | OSS |
| 4.2.x | 4.2.7 | Enterprise Support Only |
| 4.1.x | 4.1.10 | Enterprise Support Only |
| 3.1.x | 3.1.14 | Enterprise Support Only |
Older unsupported versions are also affected. Organizations on older branches must either procure enterprise support or migrate to a supported open source branch.
Affected Systems and Versions
This vulnerability affects Spring Cloud Config Server instances that use Google Secrets Manager as a backend. The following version ranges are confirmed affected:
- Spring Cloud Config 3.1.x: versions 3.1.0 through 3.1.13 (inclusive)
- Spring Cloud Config 4.1.x: versions 4.1.0 through 4.1.9 (inclusive)
- Spring Cloud Config 4.2.x: versions 4.2.0 through 4.2.6 (inclusive)
- Spring Cloud Config 4.3.x: versions 4.3.0 through 4.3.2 (inclusive)
- Spring Cloud Config 5.0.x: versions 5.0.0 through 5.0.2 (inclusive)
The vulnerable configuration specifically requires:
- Spring Cloud Config Server deployed with Google Secrets Manager as the configuration backend
- The Config Server's GCP service account having IAM access to more than one GCP project
- Network accessibility to the Config Server endpoint
Older, unsupported versions of Spring Cloud Config are also affected but will not receive patches.
References
- Spring Security Advisory: CVE-2026-40981
- NVD Entry for CVE-2026-40981
- Patch Commit 4e93ce5: "Add allowed-project-ids property"
- Spring Cloud Config v5.0.3 Release
- Spring Cloud Config v4.3.3 Release
- CWE-639: Authorization Bypass Through User Controlled Key
- Spring Framework Overview
- VMware Tanzu Spring



