CRITICAL spring4shellmutual tls

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.suffix that triggers Spring’s DataBinder to instantiate a FileWriter and write arbitrary code to the webapp’s WEB-INF/classes directory.
  • 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 SettingScanner ReachabilityDetection Outcome
need (required) with proper trust storeBlocked – TLS handshake fails before HTTPmiddleBrick reports "Mutual TLS required – cannot test unauthenticated surface" and does not attempt further checks.
need with weak or missing trust storeMay succeed if attacker can present any cert (self‑signed) that is acceptedIf handshake succeeds, middleBrick proceeds to test parameters and can flag Spring4shell.
optionalScanner connects without a cert; server falls back to unauthenticated modeFull scan runs; Spring4shell detected if present.
No mTLSScanner connects normallyStandard 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.

# 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?
No. Mutual TLS protects the transport layer but does not inspect or sanitize HTTP parameters. If an attacker can present a valid client certificate (or if mTLS is misconfigured as optional), the Spring4shell data‑binding vector can still be reached and exploited.
How can I use middleBrick to test an API that requires Mutual TLS?
middleBrick performs unauthenticated scanning. If Mutual TLS is set to 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.