agentsclimarketplace

Apache druid security

Skill cxcscmu/SkillLearnBench/skills/b1-one-shot-claude-sonnet-4-6/fix-security-bug/apache-druid-security

Security patching for Apache Druid - covers JavaScript execution vulnerabilities, sampler endpoint protection, and filter validation patterns.From its SKILL.md

Install
npx -y skills add cxcscmu/SkillLearnBench --skill apache-druid-security

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

3.8 KB, 833 tokens by cl100k_base, as published. Nobody here has run it

Apache Druid Security Patching

Overview

Apache Druid is a real-time analytics database. Key security concern: JavaScript execution via filter/transform specs in ingestion tasks and the sampler endpoint.

CVE-2021-25646 - JavaScript Filter RCE

Vulnerability Mechanism

  • JavaScriptDimFilter uses @JacksonInject JavaScriptConfig config to get JavaScript enabled status
  • @JacksonInject with default value="" allows Jackson to fall back to JSON input when the injectable value isn't found or when useInput=OptBoolean.DEFAULT
  • Exploit: Send "": {"enabled": true} in the filter JSON to inject a permissive JavaScriptConfig
  • This bypasses the server-level druid.javascript.enabled=false setting
  • The Rhino JS engine has no ClassShutter → full Java class access → Runtime.exec() possible

Affected Files

  • processing/src/main/java/org/apache/druid/query/filter/JavaScriptDimFilter.java
  • indexing-service/src/main/java/org/apache/druid/indexing/overlord/sampler/InputSourceSampler.java
  • core/src/main/java/org/apache/druid/js/JavaScriptConfig.java

Fix 1: Block JSON Override of @JacksonInject (Root Cause)

// In JavaScriptDimFilter constructor, add useInput = OptBoolean.FALSE:
import com.fasterxml.jackson.annotation.OptBoolean;

@JsonCreator
public JavaScriptDimFilter(
    @JsonProperty("dimension") String dimension,
    @JsonProperty("function") String function,
    @JsonProperty("extractionFn") @Nullable ExtractionFn extractionFn,
    @JsonProperty("filterTuning") @Nullable FilterTuning filterTuning,
    @JacksonInject(useInput = OptBoolean.FALSE) JavaScriptConfig config  // KEY FIX
)

Fix 2: Server-Side Validation in Sampler (Defense in Depth)

// In InputSourceSampler.java - inject JavaScriptConfig via Guice:
import com.google.inject.Inject;
import org.apache.druid.js.JavaScriptConfig;
import org.apache.druid.query.filter.JavaScriptDimFilter;

public class InputSourceSampler {
    private final JavaScriptConfig javascriptConfig;

    @Inject
    public InputSourceSampler(JavaScriptConfig javascriptConfig) {
        this.javascriptConfig = javascriptConfig;
    }

    public SamplerResponse sample(...) {
        // Add BEFORE processing:
        if (!javascriptConfig.isEnabled()) {
            validateNoJavaScriptFilter(nonNullDataSchema.getTransformSpec().getFilter());
        }
    }

    private void validateNoJavaScriptFilter(@Nullable DimFilter filter) {
        if (filter instanceof JavaScriptDimFilter) {
            throw new SamplerException("JavaScript is disabled. Set druid.javascript.enabled=true to enable.");
        }
        // Also handle composite filters (AND/OR/NOT)
    }
}

Key Architecture Notes

JavaScript Execution Path

  1. POST /druid/indexer/v1/samplerSamplerResource.post()
  2. IndexTaskSamplerSpec.sample()InputSourceSampler.sample()
  3. dataSchema.getTransformSpec().decorate(reader)
  4. TransformingInputSourceReaderTransformer
  5. filter.toFilter()JavaScriptDimFilter.getPredicateFactory() ← security check is here

Guice-Managed Components

  • InputSourceSampler is bound as Singleton in SamplerModule
  • JavaScriptConfig is bound in JavaScriptModule from druid.javascript config
  • Jackson @JacksonInject uses Guice's InjectableValues when available

Build Command

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

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.