Spring4shell with Mutual Tls
How Spring4shell Manifests in Mutual TLS
Spring4shell (CVE-2022-22965) is a remote code execution vulnerability in the Spring Framework that stems from unsafe data binding on request parameters. When an application uses Mutual TLS (mTLS) for client authentication, the vulnerability does not disappear; mTLS only protects the transport layer. If an attacker can present a valid client certificate (e.g., by stealing one or exploiting a misconfiguration), they can still send HTTP requests that reach the Spring controller and trigger the malicious data‑binding chain.
Typical attack flow in an mTLS‑protected endpoint:
- The attacker establishes a TLS handshake and presents a client certificate that passes the server’s trust store.
- During the handshake, the server populates standard SSL headers (e.g.,
SSL_CLIENT_S_DN,SSL_CLIENT_VERIFY) but does not sanitize request parameters. - The attacker sends a POST request with a crafted parameter such as
class.module.classLoader.resources.context.parent.pipeline.first.suffixthat triggers Spring’sDataBinderto instantiate aFileWriterand write arbitrary code to the webapp’sWEB-INF/classesdirectory. - Once the malicious class is written, a subsequent request invokes it, achieving remote code execution despite the presence of mTLS.
Importantly, mTLS does not inspect or filter HTTP parameters, so the vulnerability remains exploitable at the application layer. If mTLS is set to need (required) and the attacker lacks a valid client cert, the connection is terminated before the HTTP layer is reached, effectively mitigating the issue. However, many deployments use optional or misconfigured trust stores, leaving the attack surface open.
Mutual TLS‑Specific Detection
Detecting Spring4shell in an mTLS environment requires the scanner to either bypass the client‑certificate requirement or verify that the requirement is improperly configured. middleBrick performs unauthenticated black‑box scanning; therefore its behavior depends on how mTLS is enforced:
| mTLS Setting | Scanner Reachability | Detection Outcome |
|---|---|---|
need (required) with proper trust store | Blocked – TLS handshake fails before HTTP | middleBrick reports "Mutual TLS required – cannot test unauthenticated surface" and does not attempt further checks. |
need with weak or missing trust store | May succeed if attacker can present any cert (self‑signed) that is accepted | If handshake succeeds, middleBrick proceeds to test parameters and can flag Spring4shell. |
optional | Scanner connects without a cert; server falls back to unauthenticated mode | Full scan runs; Spring4shell detected if present. |
| No mTLS | Scanner connects normally | Standard Spring4shell detection. |
When middleBrick can reach the endpoint, it sends the same set of payloads used for the original Spring4shell check (e.g., parameters targeting class.module.classLoader). A positive response (e.g., error messages indicating file write, or a change in response body) triggers a finding with severity critical and remediation guidance.
If the scanner is blocked by mTLS, middleBrick still provides valuable information: it reports that Mutual TLS is enforced and suggests verifying the trust store configuration and ensuring that client‑certificate validation is strict.
Mutual TLS‑Specific Remediation
Fixing Spring4shell in an mTLS‑protected service involves two layers: eliminating the unsafe data‑binding path and ensuring mTLS is correctly configured so that only legitimate clients can reach the application.
1. Application‑level hardening (Spring)
Upgrade Spring Framework to a patched version (≥5.3.18, ≥5.2.20). If an immediate upgrade is not possible, disable binding on dangerous classes using an InitBinder:
@Controller
public class MyController {
@InitBinder
public void safeInitBinder(ServletRequestDataBinder binder) {
// Prevent binding on fields that could lead to class loading
binder.setDisallowedFields("class.*", "Class.*", "classLoader.*", "protectionDomain.*");
}
@PostMapping("/submit")
public String handle(@ModelAttribute MyForm form) {
// processing logic
return "result";
}
}
Alternatively, use a whitelist approach with setAllowedFields if the form model is small.
2. Mutual TLS configuration hardening
Ensure that the TLS layer requires a valid client certificate and that the trust store contains only certificates from trusted sources.
- In Spring Boot (embedded Tomcat):
# application.properties
server.ssl.enabled=true
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
server.ssl.client-auth=need # require client cert
server.ssl.trust-store=classpath:truststore.p12
server.ssl.trust-store-password=changeit
server.ssl.trust-store-type=PKCS12
- In standalone Tomcat (
server.xml):
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="conf/keystore.p12" keystorePass="changeit"
truststoreFile="conf/truststore.p12" truststorePass="changeit" />
After tightening mTLS, verify that the connection fails when no client cert is presented or when an untrusted cert is used. This ensures that even if a Spring4shell‑like flaw existed in the code, an attacker without a valid client certificate could not reach the vulnerable endpoint.
Finally, run a middleBrick scan (providing a valid client cert via the CLI if needed) to confirm that the finding no longer appears and that the mutual TLS requirement is correctly enforced.
Frequently Asked Questions
Does Mutual TLS alone prevent Spring4shell exploitation?
How can I use middleBrick to test an API that requires Mutual TLS?
need with a strict trust store, the scanner will be blocked and will report that mTLS is required. To test the application layer, you must provide a valid client certificate (e.g., via the CLI option --cert) or temporarily set mTLS to optional in a staging environment for the scan.