{
  "ticket_id": "CVE-2026-40899",
  "code_root": "external/dataease",
  "source": {
    "type": "cve",
    "cve_id": "CVE-2026-40899",
    "advisory_url": "https://www.ox.security/blog/from-auth-bypass-to-rce-a-4-vulnerability-exploit-chain-in-dataease/",
    "vendor": "FIT2CLOUD / DataEase",
    "product": "DataEase",
    "repo": "https://github.com/dataease/dataease"
  },
  "facts": {
    "cve_id": "CVE-2026-40899",
    "issue_summary": "DataEase keeps a server-side blocklist of forbidden JDBC connection parameters (e.g. allowLoadLocalInfile, allowMultiQueries, autoDeserialize) to prevent a privileged user from configuring a malicious datasource. The blocklist is held on a Java bean whose class is annotated with Lombok's @Data, which auto-generates a public setter for the blocklist field itself. Spring's JSON binding then accepts a request body that overwrites the blocklist with an empty list before the validator runs, after which any JDBC parameter can be set on the JDBC URL.",
    "vulnerability_type": "Improper enforcement of configuration validation via Lombok @Data setter exposure (CWE-915 / CWE-470)",
    "suspected_cwe": ["CWE-915", "CWE-470"],
    "affected_versions": "DataEase community-edition <= v2.10.20",
    "fixed_versions": ["v2.10.21"],
    "reproduce_version": "v2.10.20",
    "verify_fixed_version": "v2.10.21",
    "repo_url": "https://github.com/dataease/dataease.git",
    "vulnerable_ref": "v2.10.20",
    "fixed_ref": "v2.10.21",
    "code_root": "external/dataease",
    "attacker_access": "authenticated admin (chains from CVE-2026-23958 in the public chain; for standalone reproduction the default 'admin / DataEase@123456' credential is sufficient)",
    "primary_entry_point": "POST /de2api/datasource/add (or /validate) with a JSON body that includes the blocklist field as an empty array AND a custom 'extraParams' containing the unblocked parameter",
    "validation_target": "Server accepts a JDBC URL that contains allowLoadLocalInfile=true; opening a connection causes the MySQL JDBC client to honor LOCAL INFILE responses from the server it connects to.",
    "evidence_strategy": "Stand up a small TCP listener that speaks just enough of the MySQL handshake to send a LOCAL INFILE packet for /etc/passwd, then submit the crafted datasource and observe the file contents returned in the connection-test response (or written to the DataEase server log).",
    "fixed_behavior": "v2.10.21 either removes @Data from the configuration class, adds a non-setter blocklist (private final, populated in constructor), or runs the blocklist check on a defensive copy that ignores user-supplied overrides."
  }
}
