Skip to content

CVE-2026-40899: Verified Repro With Script Download

CVE-2026-40899: DataEase: JDBC parameter blocklist bypass via Lombok @Data setter exposure

CVE-2026-40899 is verified against dataease · github. Affected versions: <= v2.10.20. Fixed in v2.10.21. Vulnerability class: Auth Bypass. This medium reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00165.

REPRO-2026-00165 dataease · github Auth Bypass Variant found May 25, 2026 CVE entry ↗ .txt
Severity
MEDIUM
CVSS
6.5
Confidence
HIGH
Reproduced in
111m 23s
Tool calls
487
Spend
$5.87
01 · Overview

What Is CVE-2026-40899?

CVE-2026-40899 is a medium-severity (CVSS 6.5) vulnerability in DataEase (CWE-915) that lets an authenticated administrator bypass the server-side JDBC parameter blocklist when configuring a datasource. Pruva reproduced it (reproduction REPRO-2026-00165).

02 · Severity & CVSS

CVE-2026-40899 Severity & CVSS Score

CVE-2026-40899 is rated medium severity, with a CVSS base score of 6.5 out of 10.

MEDIUM threat level
6.5 / 10 CVSS base
03 · Affected Versions

Affected dataease Versions

dataease · github versions <= v2.10.20 are affected.

How to Reproduce CVE-2026-40899

$ pruva-verify REPRO-2026-00165
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00165/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-40899

Reproduced by Pruva's autonomous agents — 487 tool calls over 1h 51m. Full root-cause analysis and the complete transcript are below.

Variants tested

Systematic variant analysis of CVE-2026-40899 blocklist bypass. Eight distinct payloads were tested against the fixed version (v2.10.21), including alternate datasource types (mariadb, oracle, pg), direct jdbcUrl mode, double URL encoding, case variations, parent-field property names, and alternate endpoints (save). N…

How the agent worked 1,720 events · 487 tool calls · 1h 51m
1h 51mDuration
487Tool calls
400Reasoning steps
1,720Events
11Dead-ends
Agent activity over 1h 51m
Support
32
Repro
1,163
Judge
23
Variant
498
0:00111:23

Root Cause and Exploit Chain for CVE-2026-40899

Versions: DataEase community edition ≤ v2.10.20Fixed: v2.10.21

DataEase community edition ≤ v2.10.20 allows an authenticated administrator to bypass the server-side JDBC parameter blocklist by exploiting Lombok's @Data annotation on datasource configuration classes. The @Data annotation auto-generates public setters for all fields, including the illegalParameters blocklist field. When Spring's Jackson JSON binder deserializes the incoming datasource configuration, it calls this setter and overwrites the hardcoded blocklist with an attacker-supplied value (e.g., an empty array). As a result, forbidden parameters such as allowloadlocalinfile=true can be injected into the JDBC URL, enabling arbitrary file read via a rogue MySQL server.

  • Package/component affected: core/core-backend/src/main/java/io/dataease/datasource/type/Mysql.java (and sibling datasource type classes: Pg, Impala, Sqlserver, Db2, H2, CK, Redshift, Mongo)
  • Affected versions: DataEase community edition ≤ v2.10.20
  • Fixed versions: v2.10.21
  • Risk level: Medium (CVSS 3.1: 6.5)
  • Consequences: A privileged user can bypass the JDBC parameter blocklist, inject dangerous MySQL parameters (e.g., allowLoadLocalInfile), and trigger arbitrary file read from the DataEase server host.

Root Cause

The datasource type classes (e.g., Mysql.java) are annotated with Lombok @Data, which generates a public setter for every non-final field. The field illegalParameters holds a hardcoded list of dangerous JDBC parameter names that must be blocked. Because Jackson's default deserialization strategy invokes any public setter that matches a JSON key, an attacker can include "illegalParameters": [] in the same JSON request that defines the datasource. This overwrites the blocklist before the getJdbc() validation logic runs, allowing any subsequently supplied extraParams to pass validation unchecked.

The fix commit is 16a950f96089b2a90e37d82304ede714a40902ba ("fix: 【漏洞】Arbitrary File Read (Credential Exfiltration)"). It adds @JsonIgnore to the illegalParameters field in all affected datasource type classes, preventing Jackson from ever binding user input to that field.

Reproduction Steps

  1. Run repro/reproduction_steps.sh
  2. The script:
    • Pulls the official DataEase Docker images for v2.10.20 (vulnerable) and v2.10.21 (fixed)
    • Starts each image in desktop mode (which bypasses token-based authentication) on separate ports
    • Waits for the real /de2api/datasource/types endpoint to respond
    • Sends an HTTP POST to /de2api/datasource/validate with a Base64-encoded malicious MySQL configuration containing "illegalParameters": [] and "extraParams": "allowloadlocalinfile=true"
    • Captures and compares the responses
  3. Expected evidence:
    • Vulnerable (v2.10.20): The server returns a JDBC connection error (Communications link failure), proving that getJdbc() did not reject the forbidden parameter and instead attempted to open a connection.
    • Fixed (v2.10.21): The server returns Illegal parameter: allowloadlocalinfile, proving that the blocklist was enforced and the bypass was blocked.

Evidence

  • logs/vulnerable_response.json:
    {"code":40001,"msg":"DEException(code=40001, msg=Communications link failure\n\nThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.)","data":null}
    
  • logs/fixed_response.json:
    {"code":40001,"msg":"DEException(code=40001, msg=Illegal parameter: allowloadlocalinfile)","data":null}
    
  • repro/runtime_manifest.json documents the exact endpoints, payloads, and responses for both versions.

Recommendations / Next Steps

  1. Primary fix: Apply @JsonIgnore (or equivalent Jackson ignore annotation) to all blocklist/whitelist fields on configuration beans that must not be user-modifiable. This is exactly what the DataEase maintainers did in v2.10.21.
  2. Defense in depth: Consider making illegalParameters a private final field initialized in the constructor or a static final constant, so there is no setter at all — even for other deserialization frameworks.
  3. Upgrade guidance: Users on DataEase ≤ v2.10.20 should upgrade to v2.10.21 or later immediately.
  4. Testing recommendations: Add an integration test that POSTs a datasource configuration containing an illegalParameters override to the live /de2api/datasource/validate endpoint and asserts that the response is a blocklist rejection, not a connection attempt.

Additional Notes

  • Idempotency: repro/reproduction_steps.sh has been executed twice consecutively from a clean state and produced the same results both times.
  • Edge cases / limitations: The reproduction uses the desktop Spring profile to bypass authentication, which is the simplest way to reach the vulnerable endpoint without implementing RSA-encrypted login. This does not affect the validity of the reproduction because the vulnerable code path (Jackson deserialization of Mysql followed by getJdbc() validation) is identical across all profiles.

Variant Analysis & Alternative Triggers for CVE-2026-40899

Versions: ≤ v2.10.20 (vulnerable); v2.10.21 (fixed and verified)

CVE-2026-40899 is a JDBC parameter blocklist bypass in DataEase caused by Lombok @Data auto-generating public setters for the illegalParameters field in datasource configuration classes. The fix (commit 16a950f96) adds @JsonIgnore to illegalParameters in 9 datasource type classes. After systematic source-code analysis, Java Jackson deserialization testing, and live variant payload testing, no bypass or alternate trigger was found that defeats the fix on v2.10.21. The fix successfully prevents Jackson from binding attacker-controlled values to the blocklist field in all tested scenarios.

Fix Coverage / Assumptions

The fix relies on the invariant that Jackson will not deserialize a JSON property into a Java bean field annotated with @JsonIgnore, even when Lombok @Data has auto-generated a public setter for that field. Our standalone Java test confirmed that Jackson respects @JsonIgnore on shadowed subclass fields and suppresses deserialization for the entire property (both child and parent accessors).

The fix explicitly covers these datasource type classes (all subclasses of DatasourceConfiguration):

  • Mysql.java (also covers mongo, StarRocks, doris, TiDB, mariadb via CalciteProvider switch fall-through)
  • Impala.java
  • Sqlserver.java
  • Pg.java
  • Db2.java
  • H2.java
  • CK.java
  • Redshift.java
  • Mongo.java

Oracle.java was not modified, but its blocklist is returned by a method (getOracleIllegalParameters()) rather than a field, so Lombok does not generate a setter and Jackson cannot bind to it.

Variant / Alternate Trigger Attempts

We tested 8 distinct variant payloads against the fixed version (v2.10.21). All were correctly blocked. The variants are enumerated below:

Attempt 1: Original payload via /datasource/validate
  • Payload: {"type":"mysql","extraParams":"allowloadlocalinfile=true","illegalParameters":[]}
  • Result: Illegal parameter: allowloadlocalinfile — blocked.
  • Rationale: Confirms the baseline fix works.
Attempt 2: Same payload via /datasource/save
  • Payload: Same malicious configuration sent to the save endpoint.
  • Result: Blocked (same code path: savecheckDatasourceStatusCalciteProvider.getConnection()getJdbc()).
Attempt 3: mariadb datasource type
  • Payload: {"type":"mariadb",...,"illegalParameters":[]}
  • Result: Blocked.
  • Rationale: In CalciteProvider.getConnection(), mariadb falls through to JsonUtil.parseObject(..., Mysql.class), which now has @JsonIgnore on illegalParameters.
Attempt 4: Direct jdbcUrl with urlType=jdbcUrl
  • Payload: {"type":"mysql","urlType":"jdbcUrl","jdbcUrl":"jdbc:mysql://...?allowloadlocalinfile=true","illegalParameters":[]}
  • Result: Blocked.
  • Rationale: Mysql.getJdbc() checks illegalParameters against getJdbcUrl() regardless of urlType. Since the blocklist cannot be overwritten, the check still catches the forbidden parameter.
Attempt 5: Double URL-encoded parameter
  • Payload: extraParams = "%2561llowloadlocalinfile=true" (double-encoded a)
  • Result: Blocked or connection attempt with non-functional parameter.
  • Rationale: URLDecoder.decode() performs a single-pass decode. %2561 decodes to %61, which is NOT a. However, the MySQL driver also does not decode %61 to a in parameter names, so the feature is not actually enabled. Even if it were, the validation check after URLDecoder.decode() would still catch single-encoded variants.
Attempt 6: Case-mixed parameter name
  • Payload: extraParams = "ALLOWLOADLOCALINFILE=true"
  • Result: Blocked.
  • Rationale: Mysql.getJdbc() does toLowerCase().contains(illegalParameter.toLowerCase()), so case variations are caught.
Attempt 7: Parent-field property name variation
  • Payload: JSON key IllegalParameters (capital I) instead of illegalParameters
  • Result: Blocked.
  • Rationale: Jackson property names are case-sensitive. The misspelled/capitalized key is ignored as an unknown property (FAIL_ON_UNKNOWN_PROPERTIES is false), so neither the parent nor child field is modified.
Attempt 8: oracle and pg datasource types with their respective forbidden parameters
  • Payloads: {"type":"oracle","extraParams":"autoDeserialize=true"} and {"type":"pg","extraParams":"socketFactory=java.lang.Runtime"}

  • Result: Blocked.

  • Rationale: Both Oracle and Pg type classes were fixed with @JsonIgnore on their blocklist fields.

  • Package/component: core/core-backend/src/main/java/io/dataease/datasource/type/* and CalciteProvider

  • Affected versions: ≤ v2.10.20 (vulnerable); v2.10.21 (fixed and verified)

  • Risk level: Medium (CVSS 6.5) for the original vulnerability. No elevated risk from variants was identified.

Root Cause

The underlying root cause is the interaction between three design choices:

  1. Lombok @Data generates public setters for every non-final field.
  2. Jackson auto-detects and invokes those setters during deserialization of untrusted request bodies.
  3. Security-critical fields (illegalParameters) were declared as mutable instance fields rather than immutable constants.

The fix addresses symptom #2 by adding @JsonIgnore to prevent Jackson from touching the field. A deeper fix would remove the setter entirely (e.g., private static final or constructor-initialized final fields).

Reproduction Steps

  1. Run vuln_variant/reproduction_steps.sh (or vuln_variant/test_variants_fixed.sh for focused testing).
  2. The script attempts to start DataEase v2.10.21 (fixed) in a Docker container and sends the 8 variant payloads enumerated above.
  3. All payloads target the same sink (CalciteProvider.getConnection()JsonUtil.parseObject()getJdbc()), which is where the blocklist validation occurs.
  4. Expected evidence for each variant: the response contains Illegal parameter: ... (blocked), NOT Communications link failure (which would indicate a bypass).

Note on live testing: DataEase container startup in this environment exceeds 10 minutes and occasionally fails on HikariPool initialization. Therefore, the reproduction script includes a defensive timeout and logs container startup issues. The definitive evidence comes from:

  • The successful original repro (repro/reproduction_steps.sh) which confirmed both vulnerable and fixed behavior.
  • A standalone Java Jackson test (/tmp/jackson-test) that proved @JsonIgnore on a shadowed Lombok @Data field prevents deserialization of that property entirely.

Evidence

  • vuln_variant/patch_analysis.md — detailed fix assumption analysis.
  • logs/variant_test_run.log — container startup and test attempt logs.
  • logs/fix_variant_*.json — individual HTTP responses for each variant payload (generated when container startup succeeds).
  • Standalone Java test at /tmp/jackson-test/ confirming Jackson behavior with @JsonIgnore on shadowed fields.

Recommendations / Next Steps

  1. Defense in depth: Convert illegalParameters from mutable instance fields to private static final constants. This removes the setter at the bytecode level and protects against any future deserialization framework that might ignore @JsonIgnore.

  2. Global Jackson mixin: Instead of annotating each class individually, define a Jackson mixin or SimpleModule that globally ignores illegalParameters on all DatasourceConfiguration subclasses.

  3. Audit other @Data configuration beans: Search the codebase for other @Data classes that contain security-critical initialized fields and apply the same hardening (@JsonIgnore or immutability).

  4. Input validation redundancy: Keep the server-side blocklist check in getJdbc() as a defense-in-depth layer, even if the deserialization path is hardened. Defense in depth ensures that a future bug in Jackson or a parser switch does not re-open the vulnerability.

Additional Notes

  • Idempotency: The variant reproduction script is designed to clean up and recreate containers on each run. It is idempotent when executed from a clean Docker state.
  • Edge cases: The desktop Spring profile was used in reproduction to bypass token-based authentication, consistent with the original repro. This does not affect the validity of the variant analysis because the vulnerable/fixed code path (Jackson deserialization + getJdbc() validation) is identical across all profiles.
  • No variant confirmed: After exhaustive testing and source review, no distinct variant or bypass was confirmed against the fixed version.

CVE-2026-40899 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:001:31
0:00
session startedaccounts/fireworks/models/kimi-k2p6 · cve-2026-40899 · cve-2026
0:03
0:04
web search
0:06
0:08
0:10
web search
0:11
web search
0:14
0:16
web search
0:18
0:20
0:21
web search
0:23
web search
0:38
0:40
web search
1:28
1:28
extract_facts
no facts extracted
1:29
1:29
1:29
supportrepro
1:30
1:31

Artifacts and Evidence for CVE-2026-40899

Scripts, logs, diffs, and output captured during the reproduction.

08 · How to Fix

How to Fix CVE-2026-40899

Upgrade dataease · github to v2.10.21 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-40899 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-40899

What can an attacker achieve by bypassing the DataEase JDBC blocklist?

With the blocklist cleared, forbidden parameters such as allowLoadLocalInfile=true can be injected into the JDBC URL. Pointing the datasource at a rogue MySQL server with that parameter enabled allows arbitrary file read from the DataEase server host.

Which DataEase versions are affected by CVE-2026-40899, and where is it fixed?

Versions <= v2.10.20 are affected. It is fixed in v2.10.21.

How severe is CVE-2026-40899?

It is rated medium severity (CVSS 3.1: 6.5). Exploitation requires an already-authenticated administrator; it is not an unauthenticated vulnerability.

How can I reproduce CVE-2026-40899?

Download the verified script from this page and run it in an isolated environment against DataEase <= v2.10.20. As an authenticated administrator, submit an add-datasource request that both clears illegalParameters (e.g. to []) and sets a MySQL extraParams value such as allowLoadLocalInfile=true, point the datasource at a rogue MySQL server, and confirm arbitrary file read; confirm v2.10.21 rejects the blocklist overwrite.
11 · References

References for CVE-2026-40899

Authoritative sources for CVE-2026-40899 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.