Run2 druid cve 2021 25646
[COLM'26] SkillLearnBench is the first benchmark for evaluating continual learning methods that automatically generate agent skills.
npx -y skills add cxcscmu/SkillLearnBench --skill run2_druid-cve-2021-25646Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Complete guide to patching Apache Druid CVE-2021-25646 - JavaScript RCE via Jackson @JacksonInject bypass with empty JSON key
SKILL.md
3.3 KB, as published. Nobody here has run it
Apache Druid CVE-2021-25646 - Complete Patch Guide
Vulnerability Summary
CVE-2021-25646 - Remote Code Execution in Apache Druid <= 0.20.0
Attack Vector: Authenticated attackers send crafted JSON to /druid/indexer/v1/sampler
Root Cause: @JacksonInject(useInput = DEFAULT) allows JSON to override server-injected JavaScriptConfig
CVSS: Critical
How the Exploit Works
- Druid uses
@JacksonInject JavaScriptConfig configto inject server-side config (JS disabled by default) - Jackson's
@JacksonInjectwithuseInput = OptBoolean.DEFAULTallows JSON to OVERRIDE the injectable - The empty JSON key
""acts as the Jackson injection ID for theJavaScriptConfigparameter - Attacker sends
"": {"enabled": true}→ Jackson creates a newJavaScriptConfig(enabled=true) - This overrides the server's config → JavaScript executes arbitrary code via
Runtime.exec()
{
"type": "javascript",
"function": "function(){ java.lang.Runtime.getRuntime().exec('malicious_cmd'); }",
"": { "enabled": true }
}
The Fix
Change useInput from default (DEFAULT/TRUE behavior) to OptBoolean.FALSE on ALL
@JacksonInject JavaScriptConfig config parameters:
// BEFORE (vulnerable)
@JacksonInject JavaScriptConfig config
// AFTER (patched)
@JacksonInject(useInput = OptBoolean.FALSE) JavaScriptConfig config
Also add: import com.fasterxml.jackson.annotation.OptBoolean;
All 7 Affected Files
| File | Module |
|---|---|
core/src/main/java/org/apache/druid/data/input/impl/JavaScriptParseSpec.java | core |
processing/src/main/java/org/apache/druid/query/filter/JavaScriptDimFilter.java | processing |
processing/src/main/java/org/apache/druid/query/aggregation/JavaScriptAggregatorFactory.java | processing |
processing/src/main/java/org/apache/druid/query/aggregation/post/JavaScriptPostAggregator.java | processing |
processing/src/main/java/org/apache/druid/query/extraction/JavaScriptExtractionFn.java | processing |
server/src/main/java/org/apache/druid/server/router/JavaScriptTieredBrokerSelectorStrategy.java | server |
indexing-service/src/main/java/org/apache/druid/indexing/overlord/setup/JavaScriptWorkerSelectStrategy.java | indexing-service |
Build Command
The sampler is in indexing-service; build with -pl indexing-service -am to build it and dependencies:
cd /root/druid
mvn clean package -DskipTests \
-Dcheckstyle.skip=true -Dpmd.skip=true -Dforbiddenapis.skip=true \
-Dspotbugs.skip=true -Danimal.sniffer.skip=true -Denforcer.skip=true \
-Djacoco.skip=true -Ddependency-check.skip=true \
-pl '!web-console' -pl indexing-service -am
Output JAR: indexing-service/target/druid-indexing-service-0.20.0.jar
Patch File Generation
After applying source changes:
git diff > /root/patches/cve-2021-25646-javascript-inject-bypass.patch
Verification
After patch, the exploit payload returns HTTP 500 with "JavaScript is disabled"
(from Preconditions.checkState(config.isEnabled(), "JavaScript is disabled"))
because the injected value (enabled=false) can no longer be overridden by JSON.