Skip to content

Restrict freemarker ObjectWrapper instrumentation to 2.3.24+ - #12117

Draft
AlexeyKuznetsov-DD wants to merge 1 commit into
masterfrom
alexeyk/fix-muzzle-freemarker
Draft

Restrict freemarker ObjectWrapper instrumentation to 2.3.24+#12117
AlexeyKuznetsov-DD wants to merge 1 commit into
masterfrom
alexeyk/fix-muzzle-freemarker

Conversation

@AlexeyKuznetsov-DD

@AlexeyKuznetsov-DD AlexeyKuznetsov-DD commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

DO NOT MERGE, first need to decide how to fix correctly.

What Does This Do

Adds a classloader version guard to ObjectWrapperInstrumentation (freemarker 2.3.24 module), matching what DollarVariableInstrumentation already does in the same package:

static final ElementMatcher.Junction<ClassLoader> VERSION_POST_2_3_24 =
    hasClassNamed("freemarker.cache.ByteArrayTemplateLoader");

@Override
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
  return VERSION_POST_2_3_24;
}

Motivation

The freemarker-2.3.24 muzzle directive declares versions = '[2.3.24-incubating,]' with assertInverse = true, so every pre-2.3.24 version is expected to fail muzzle. ObjectWrapperInstrumentation only references freemarker.template.ObjectWrapper and freemarker.template.TemplateModel, both of which exist since 2.3.9 — so its reference check passed on old versions and the inverse assertion blew up with:

MUZZLE PASSED ObjectWrapperInstrumentation BUT FAILURE WAS EXPECTED

MuzzleVersionScanPlugin folds the classloader matcher into the pass/fail verdict (passed = mismatches.isEmpty() && classLoaderMatch), so adding the guard makes the instrumentation fail muzzle on pre-2.3.24 as declared. This showed up only intermittently on GitLab because muzzle samples the inverse version range randomly (MuzzleVersionUtils.limitLargeRanges shuffles low/high per major.minor).

Additional Notes

  • freemarker.cache.ByteArrayTemplateLoader was verified as the right version marker: absent in 2.3.9 / 2.3.20 / 2.3.23, present in 2.3.24-incubating / 2.3.34.
  • Reproduced locally by pointing MAVEN_REPOSITORY_PROXY at a file repo exposing 2.3.23 in its metadata (maven central's org.freemarker:freemarker metadata only lists 2.3.24+, which is why the inverse range is empty on plain central): muzzle-AssertFail-...-2.3.23 fails without this change and passes with it.
  • Runtime effect is intentional: on freemarker 2.3.92.3.23 the ObjectWrapper taint propagation no longer applies, aligning behavior with the module's declared support range. The 2.3.9 module ships no ObjectWrapper instrumentation, so no tested version loses coverage.
  • Tests: freemarker-2.3.24 test / latestDepTest and freemarker-2.3.9 test / version2_3_23Test all pass (42 tests).

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@AlexeyKuznetsov-DD AlexeyKuznetsov-DD added type: bug fix Bug fix inst: others All other instrumentations tag: no release notes Changes to exclude from release notes comp: asm iast Application Security Management (IAST) tag: ai generated Largely based on code generated by an AI or LLM labels Jul 30, 2026
@AlexeyKuznetsov-DD AlexeyKuznetsov-DD self-assigned this Jul 30, 2026
@AlexeyKuznetsov-DD
AlexeyKuznetsov-DD marked this pull request as ready for review July 30, 2026 19:53
@AlexeyKuznetsov-DD
AlexeyKuznetsov-DD requested a review from a team as a code owner July 30, 2026 19:53

@datadog-datadog-us1-prod datadog-datadog-us1-prod Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datadog Autotest: PASS

More details

The added classloader guard matches the existing Freemarker version split: ObjectWrapper advice remains active for 2.3.24+ and is excluded from older versions, while the 2.3.9 instrumentation remains responsible for its supported range. Runtime tests could not start because the required Gradle distribution was unavailable in the sandbox.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Datadog Autotest · Commit d7add24 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d7add24479

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +33 to +34
static final ElementMatcher.Junction<ClassLoader> VERSION_POST_2_3_24 =
hasClassNamed("freemarker.cache.ByteArrayTemplateLoader");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Return the class-loader matcher directly

When this instrumentation is registered, classLoaderMatcher() is invoked only once, so caching its result in VERSION_POST_2_3_24 adds static state and constant-pool bloat without reuse. docs/instrumentation_design_guidelines.md explicitly requires one-shot matcher values to be constructed and returned directly; inline hasClassNamed(...) in classLoaderMatcher() instead.

AGENTS.md reference: AGENTS.md:L40-L44

Useful? React with 👍 / 👎.

}

static final ElementMatcher.Junction<ClassLoader> VERSION_POST_2_3_24 =
hasClassNamed("freemarker.cache.ByteArrayTemplateLoader");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Gate hierarchy implementations on a visible package

When a custom ObjectWrapper implementation is loaded by an OSGi bundle that imports freemarker.template but not freemarker.cache, this matcher is evaluated against the implementation's bundle class loader and cannot see ByteArrayTemplateLoader. BundleWiringHelper.probeResource() only reports resources from directly imported packages, so the new module-wide guard rejects the transformation even with FreeMarker 2.3.24+, silently disabling the IAST taint propagation for that wrapper; use a version marker visible through the same imported package or a gate that does not require the unrelated cache package.

Useful? React with 👍 / 👎.

@datadog-datadog-us1-prod

Copy link
Copy Markdown

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 69.73% (+11.95%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: d7add24 | Docs | Datadog PR Page | Give us feedback!

@dd-octo-sts

dd-octo-sts Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

🟡 Java Benchmark SLOs — Performance SLO warning (near threshold)

Suite Status
Startup 🟡 warning

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 14.04 s 14.03 s [-0.7%; +0.9%] (no difference)
startup:insecure-bank:tracing:Agent 12.90 s 13.03 s [-1.8%; -0.2%] (maybe better)
startup:petclinic:appsec:Agent 16.46 s 16.61 s [-5.3%; +3.5%] (no difference)
startup:petclinic:iast:Agent 16.87 s 16.97 s [-1.4%; +0.2%] (no difference)
startup:petclinic:profiling:Agent 16.74 s 16.87 s [-1.9%; +0.4%] (no difference)
startup:petclinic:sca:Agent 16.69 s 16.53 s [+0.0%; +1.9%] (maybe worse)
startup:petclinic:tracing:Agent 15.58 s 15.60 s [-6.2%; +6.0%] (unstable)

Commit: d7add244 · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@AlexeyKuznetsov-DD
AlexeyKuznetsov-DD marked this pull request as draft July 31, 2026 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: asm iast Application Security Management (IAST) inst: others All other instrumentations tag: ai generated Largely based on code generated by an AI or LLM tag: no release notes Changes to exclude from release notes type: bug fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant