CatalogSpring4Shell
Spring4Shell (CVE-2022-22965)
Framework spring4shell
Remote code execution in Spring MVC / WebFlux data binding on JDK 9+ when deployed as a WAR on certain servlet containers. CVSS 9.8. Listed in CISA KEV on 4 Apr 2022. Public PoCs and in-the-wild scanning followed disclosure.
- Aliases
- Published
- Updated
What the bug is
Spring4Shell is the public name for CVE-2022-22965 in the Spring Framework. codeplutos and meizjm3i of AntGroup FG Security Lab reported it to VMware. Praetorian filed a secondary report. Spring published the CVE and fixes on 31 Mar 2022.
A Spring MVC or Spring WebFlux application running on JDK 9+ may be vulnerable to remote code execution via data binding. The specific exploit requires the application to run on Tomcat as a WAR deployment. Spring Boot executable JARs with an embedded container are not vulnerable to that exploit path, but Spring warns the issue is more general and other vectors may exist.
Affected Spring Framework versions include 5.3.0 to 5.3.17 and 5.2.0 to 5.2.19 (and earlier). Fixed in 5.3.18 and 5.2.20. Spring Boot 2.6.6 and 2.5.12 consume the fixed Framework. Apache Tomcat also released 10.0.20, 9.0.62, and 8.5.78 as a mitigation on the container side.
Attack path
- Data bindingRequest parameters populate a controller argument through Spring data binding on JDK 9+.
- ClassLoader accessBinding reaches ClassLoader-related properties on certain servlet containers such as Tomcat.
- Writable pathThe exploit path can manipulate access logging so a JSP webshell lands under a web application directory.
- Code execThe webshell or equivalent payload runs with the application server privileges. Conceptual impact class only.
High-level only. Not a reproduction guide.
Exploitation status
CISA KEV
Listed in CISA KEV as of .
CISA KEV entry for CVE-2022-22965, Spring Framework JDK 9+ Remote Code Execution Vulnerability. dateAdded 2022-04-04.
First seen
Seen . Source: Unit 42
Unit 42 first observed scanning traffic early on 30 Mar 2022 with HTTP requests containing test strings in the URL.
What defenders should do today
Do today
- 1
Upgrade Spring Framework
Move to Spring Framework 5.3.18 or 5.2.20 (or later). Spring Boot users should move to 2.6.6, 2.5.12, or later releases that pull in the fixed Framework.
This week
- 1
If you cannot upgrade Spring quickly
Spring documents tactical options: upgrade Tomcat to 10.0.20 / 9.0.62 / 8.5.78, set disallowedFields on WebDataBinder, or (as a last resort) leave JDK 8. Prefer upgrading Spring.
- 2
Confirm deployment shape
The classic exploit path needs JDK 9+, a vulnerable Spring web dependency, and a WAR on a standalone servlet container such as Tomcat. Inventory WAR deployments first, then review other data-binding endpoints.
- 3
Hunt for webshells under web roots
Microsoft and Unit 42 describe JSP webshells written under Tomcat web application directories after successful exploitation. Search for unexpected .jsp files and related process activity.
Detection rules
Sigma
Spring4Shell ClassLoader Parameter In Web Request
title: Spring4Shell ClassLoader Parameter In Web Request id: 7931ddcc-5eaf-51ab-8594-31098e8a64b9 status: experimental description: Detects web requests that bind class.module.classLoader properties, the request shape Microsoft documents for CVE-2022-22965 (Spring4Shell). POST bodies are not in most access logs, so this mainly catches GET-based attempts and scanners. references: - https://www.microsoft.com/en-us/security/blog/2022/04/04/springshell-rce-vulnerability-guidance-for-protecting-against-and-detecting-cve-2022-22965/ author: vuln2shell date: 2026-10-23 tags: - attack.initial-access - attack.t1190 - cve.2022-22965 logsource: category: webserver detection: selection: cs-uri-query|contains: 'class.module.classLoader' condition: selection falsepositives: - Vulnerability scanners level: highBy vuln2shell, . Source. License: CC0 1.0
Written by vuln2shell. Untested, tune before use.
Parameter name from Microsoft's guidance and Splunk's rule.
SPL (Splunk)
Web Spring4Shell HTTP Request Class Module
`stream_http` http_method IN ("POST") | stats values(form_data) as http_request_body min(_time) as firstTime max(_time) as lastTime count BY src dest http_method http_user_agent uri_path url bytes_in bytes_out | search http_request_body IN ("*class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=_*", "*class.module.classLoader.resources.context.parent.pipeline.first.pattern*","*suffix=.jsp*") | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `web_spring4shell_http_request_class_module_filter`By Michael Haag, Splunk, . Source. License: Apache-2.0
Uses Splunk ES macros and data models from splunk/security_content; the trailing _filter macro is a tuning hook.
Java Writing JSP File
| tstats `security_content_summariesonly` count FROM datamodel=Endpoint.Processes WHERE Processes.process_name IN ("java","java.exe", "javaw.exe") BY _time Processes.action Processes.dest Processes.original_file_name Processes.parent_process Processes.parent_process_exec Processes.parent_process_guid Processes.parent_process_id Processes.parent_process_name Processes.parent_process_path Processes.process Processes.process_exec Processes.process_guid Processes.process_hash Processes.process_id Processes.process_integrity_level Processes.process_name Processes.process_path Processes.user Processes.user_id Processes.vendor_product | `drop_dm_object_name(Processes)` | join process_guid [ | tstats `security_content_summariesonly` count FROM datamodel=Endpoint.Filesystem WHERE Filesystem.file_name="*.jsp*" BY _time Filesystem.action Filesystem.dest Filesystem.file_access_time Filesystem.file_create_time Filesystem.file_hash Filesystem.file_modify_time Filesystem.file_name Filesystem.file_path Filesystem.file_acl Filesystem.file_size Filesystem.process_guid Filesystem.process_id Filesystem.user Filesystem.vendor_product | `drop_dm_object_name(Filesystem)` | fields _time process_guid file_path file_name file_create_time user dest process_name] | stats count min(_time) as firstTime max(_time) as lastTime BY dest process_name process_guid file_name file_path file_create_time user | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `java_writing_jsp_file_filter`By Michael Haag, Splunk, . Source. License: Apache-2.0
Uses Splunk ES macros and data models from splunk/security_content; the trailing _filter macro is a tuning hook.
KQL (Microsoft Sentinel / Defender)
Possible SpringShell Exploitation Attempt (CVE-2022-22965)
let spring4shellstring = dynamic(["class.module.classLoader.resources.context.parent.pipeline.first.pattern="]); AzureDiagnostics | where Category in ("FrontdoorWebApplicationFirewallLog", "FrontdoorAccessLog", "ApplicationGatewayFirewallLog", "ApplicationGatewayAccessLog") | extend originalRequestUriWithArgs_s = column_ifexists("originalRequestUriWithArgs_s", ""), userAgent_s = column_ifexists("userAgent_s", ""), clientIP_s = column_ifexists("clientIP_s", ""), clientPort_d = column_ifexists("originalRequestUriWithArgs_s", ""), host_s = column_ifexists("host_s", ""), requestUri_s = column_ifexists("requestUri_s", ""), httpStatus_d = column_ifexists("httpStatus_d",""), listenerName_s = column_ifexists("listenerName_s", ""), httpMethod_s = column_ifexists("httpMethod_s", "") | where httpMethod_s =~ 'POST' | where originalRequestUriWithArgs_s has_any (spring4shellstring) or requestUri_s has_any (spring4shellstring) | summarize Total = count() by originalRequestUriWithArgs_s, userAgent_s, clientIP_s,clientPort_d, TimeGenerated, host_s, requestUri_s, httpStatus_d,listenerName_s, httpMethod_s, Category | extend IPCustomEntity = clientIP_s, timestamp = TimeGenerated, UrlCustomEntity = requestUri_s, HostCustomEntity = host_sBy Microsoft Sentinel community (Azure/Azure-Sentinel), . Source. License: MIT
CVE-2022-22965 Network Activity
DeviceNetworkEvents | where Timestamp > ago(7d) | where ActionType =~ "NetworkSignatureInspected" | where AdditionalFields contains ".jsp?cmd=" | summarize makeset(AdditionalFields, 5), min(Timestamp), max(Timestamp) by DeviceId, DeviceNameBy Microsoft Sentinel community (Azure/Azure-Sentinel), . Source. License: MIT
LogScale (CrowdStrike)
Spring4Shell ClassLoader parameter in web logs (LogScale)
/class\.module\.classLoader/i | groupBy([@host], function=count())By vuln2shell, . Source. License: CC0 1.0
Written by vuln2shell. Untested, tune before use.
Free-text form of the Sigma rule.
Suricata / Snort
ET EXPLOIT Possible SpringCore RCE/Spring4Shell Inbound (CVE-2022-22965)
alert http any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Possible SpringCore RCE/Spring4Shell Inbound (CVE-2022-22965)"; flow:established,to_server; http.request_body; content:"pipeline.first.pattern="; fast_pattern; content:"pipeline.first.suffix="; content:"pipeline.first.directory="; content:"pipeline.first.prefix="; classtype:attempted-admin; sid:2035678; rev:3; metadata:attack_target Server, created_at 2022_03_31, cve CVE_2022_22965, deployment Perimeter, deployment Internal, confidence Medium, signature_severity Major, tag Exploit, tag CISA_KEV, updated_at 2024_03_08, mitre_tactic_id TA0001, mitre_tactic_name Initial_Access, mitre_technique_id T1190, mitre_technique_name Exploit_Public_Facing_Application;)By Emerging Threats (Proofpoint), . Source. License: BSD-3-Clause (ET Open, sids 2000000-2799999)
YARA
EXPL_POC_SpringCore_0day_Webshell_Mar22_1
rule EXPL_POC_SpringCore_0day_Webshell_Mar22_1 { meta: description = "Detects webshell found after SpringCore exploitation attempts POC script" author = "Florian Roth (Nextron Systems)" reference = "https://twitter.com/vxunderground/status/1509170582469943303" date = "2022-03-30" score = 70 id = "e7047c98-3c60-5211-9ad5-2bfdfb35d493" strings: $x1 = ".getInputStream(); int a = -1; byte[] b = new byte[2048];" $x2 = "if(\"j\".equals(request.getParameter(\"pwd\")" $x3 = ".getRuntime().exec(request.getParameter(\"cmd\")).getInputStream();" condition: filesize < 200KB and 1 of them }By Florian Roth (Nextron Systems), . Source. License: DRL-1.1
More detection content
- Microsoft: SpringShell RCE vulnerability guidance
By Microsoft,
- Unit 42: SpringShell analysis
By Unit 42,
- Splunk: Spring4Shell Payload URL Request
By Splunk Threat Research Team
- Elastic: Suspicious Child Execution via Web Server (Linux)
By Elastic, . EQL; covers Tomcat Java parents.
Vendor signatures
| Signal | Log source | What to look for |
|---|---|---|
| Unit 42 / Palo Alto Spring Core RCE signature | WAF / IPS event logs | Unit 42 reports a Spring Core Remote Code Execution Vulnerability threat prevention signature that triggered 43,092 times in its first week. |
Affected frameworks and versions
Affected frameworks
| Framework | Status | Fixed version / ETA | Advisory |
|---|---|---|---|
| Spring Framework 5.3.x | Affected | 5.3.18 | Affected: 5.3.0 - 5.3.17. Fix version 5.3.18 (OSS). Source |
| Spring Framework 5.2.x and earlier | Affected | 5.2.20.RELEASE | Affected: 5.2.19.RELEASE and earlier. Fix version 5.2.20.RELEASE (OSS). Source |
| Spring Boot 2.6.x | Affected | 2.6.6 | Spring Boot 2.6.6 that depend on Spring Framework 5.3.18 have been released. Source |
| Spring Boot 2.5.x | Affected | 2.5.12 | Spring Boot 2.5.12 that depend on Spring Framework 5.3.18 have been released. Source |
| Apache Tomcat (mitigation path) | Affected | 10.0.20 / 9.0.62 / 8.5.78 | Apache Tomcat has released versions 10.0.20, 9.0.62, and 8.5.78 which close the attack vector on Tomcat's side. Source |
Timeline6
Key events
Newest first.
CISA adds CVE-2022-22965 to KEV. Microsoft publishes protection and detection guidance.
SourceApache Tomcat releases 10.0.20, 9.0.62, and 8.5.78 as a container-side mitigation.
SourceTrend Micro reports Mirai botnet payloads delivered through Spring4Shell exploitation (activity from the start of April 2022).
SourceSpring publishes CVE-2022-22965 and releases Framework 5.3.18 and 5.2.20 plus Boot 2.6.6 / 2.5.12.
SourcePublic PoC repositories such as reznok/Spring4Shell-POC appear.
SourceUnit 42 observes early scanning with Spring4Shell test strings.
Source
News & write-ups
PoC index (for defenders)
Public proof-of-concept links for defensive validation, with a source and a validation status.
Public repository created 31 Mar 2022. Description: Dockerized Spring4Shell (CVE-2022-22965) PoC application and exploit.