Skip to content

Add server.request.body.files_content AppSec address support for Jetty#11706

Open
jandro996 wants to merge 5 commits into
masterfrom
jetty-filecontent
Open

Add server.request.body.files_content AppSec address support for Jetty#11706
jandro996 wants to merge 5 commits into
masterfrom
jetty-filecontent

Conversation

@jandro996

@jandro996 jandro996 commented Jun 23, 2026

Copy link
Copy Markdown
Member

What Does This Do

  • Adds extractContents() to MultipartHelper (jetty-appsec-9.2/9.3/9.4/11.0) and PartHelper (jetty-appsec-8.1.3) to extract file content from multipart Parts, reading up to dd.appsec.max-file-content-bytes (default 4096) bytes per part, capped at dd.appsec.max-file-content-count (default 25) parts per request
  • Adds fireFilesContentEvent() to each helper, firing the server.request.body.files_content IG event via EVENTS.requestFilesContent()
  • Updates both advice classes in all five AppSec modules to fire the content event sequentially after the filenames event: t = fireFilenamesEvent(...); if (t == null) t = fireFilesContentEvent(...)
  • Form fields (parts with null submitted filename) are excluded; files with empty filename ("") are included for content inspection but excluded from filenames — matches the filter established in Add server.request.body.files_content AppSec address for Tomcat and Netty multipart #11198
  • Content is decoded via MultipartContentDecoder.readInputStream() with charset detection from the part's Content-Type header
  • For Jetty 8.1.3, filenameFromPart() (Content-Disposition header parsing) is used in place of getSubmittedFileName(), which was only added in Servlet 3.1
  • Adds unit tests for extractContents() in all five modules (null/empty, form-field skip, empty-filename include, content read, byte truncation, IOException fallback, count cap)
  • Enables testBodyFilesContent() in integration test classes for Jetty 8.x, 9.2, 9.3, 9.4, 10.0, and 11.0

Motivation

Extends the server.request.body.files_content WAF address to Jetty, following the Tomcat/Netty implementation in #11198 and building on the Jetty filenames support from #10988.

Additional Notes

The content event fires sequentially after the filenames event — only when filenames did not block. This matches the intent from #11137 (commons-fileupload). The MAX_CONTENT_BYTES and MAX_FILES_TO_INSPECT constants are static final fields on the helper classes (not on advice inner classes with @RequiresRequestContext) to avoid muzzle validation failures at CI.

Contributor Checklist

Jira ticket: N/A

Note: Once your PR is ready to merge, add it to the merge queue by commenting /merge. /merge -c cancels the queue request. /merge -f --reason "reason" skips all merge queue checks; please use this judiciously, as some checks do not run at the PR-level. For more information, see this doc.

- Add extractContents(), readFileContent(), and fireFilesContentEvent()
  to MultipartHelper (9.2/9.3/9.4/11.0) and PartHelper (8.1.3)
- Fire files_content event sequentially after filenames event in all
  five Jetty AppSec advice classes
- Add unit tests for extractContents in all five modules
- Enable testBodyFilesContent() in integration test classes for all
  instrumented Jetty versions (8.x, 9.2, 9.3, 9.4, 10.0, 11.0)
@jandro996 jandro996 added type: enhancement Enhancements and improvements comp: asm waf Application Security Management (WAF) labels Jun 23, 2026
@jandro996 jandro996 changed the title Add server.request.body.files_content WAF address support to Jetty Add server.request.body.files_content AppSec address support for Jetty Jun 23, 2026
@jandro996

Copy link
Copy Markdown
Member Author

@codex review

@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: 66fad6bbfd

ℹ️ 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".

@datadog-prod-us1-5

This comment has been minimized.

@dd-octo-sts

dd-octo-sts Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

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 13.98 s 13.93 s [-0.2%; +0.9%] (no difference)
startup:insecure-bank:tracing:Agent 12.97 s 12.97 s [-0.7%; +0.6%] (no difference)
startup:petclinic:appsec:Agent 16.89 s 16.55 s [+1.0%; +3.1%] (significantly worse)
startup:petclinic:iast:Agent 16.91 s 16.88 s [-0.5%; +0.8%] (no difference)
startup:petclinic:profiling:Agent 16.78 s 16.92 s [-1.8%; +0.1%] (no difference)
startup:petclinic:sca:Agent 16.92 s 16.61 s [+1.0%; +2.8%] (maybe worse)
startup:petclinic:tracing:Agent 16.11 s 16.04 s [-0.6%; +1.5%] (no difference)

Commit: 8fdf93cb · 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.

…ring-sensitive test

- RequestGetPartsInstrumentation (Jetty 8): add bodyBlock == null guard before
  fireFilesContentEvent in both GetFilenamesAdvice and GetPartAdvice, consistent
  with Tomcat, Netty, and Jersey implementations (PR #11198, #11229)
- HttpServerTest: change max-files-limit assertion to count-based check; Jetty
  returns parts in HashMap order (not insertion order), so checking for a specific
  file number by position was fragile
@jandro996

Copy link
Copy Markdown
Member Author

Addressed in d605e01:

@jandro996 jandro996 marked this pull request as ready for review June 23, 2026 13:38
@jandro996 jandro996 requested review from a team as code owners June 23, 2026 13:38
@jandro996 jandro996 requested review from amarziali, claponcet, manuel-alvarez-alvarez and vandonr and removed request for a team June 23, 2026 13:38
@jandro996 jandro996 requested a review from claponcet June 24, 2026 11:52

@amarziali amarziali left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok for apm-java (we only own the HttpServerTest) so our review is not blocking. However I left comments (not exhaustive since there are more occurrences) about the fact that there are a lot of exception logged. Those are surfaced through the telemetry and needs to get triaged. If those logs are not actionable I suggest to use the EXCLUDE_TELEMETRY marker

Add EXCLUDE_TELEMETRY marker to all log.debug calls in
PartHelper/MultipartHelper that handle exceptions from user-controlled
data (malformed parts, stream I/O failures). These are not actionable
from the agent side and would pollute telemetry signal.

The MethodHandle invocation failure in PartHelper.getAllParts is
intentionally left without the marker — that failure IS actionable
as it indicates an instrumentation-internal issue.
@jandro996

Copy link
Copy Markdown
Member Author

ok for apm-java (we only own the HttpServerTest) so our review is not blocking. However I left comments (not exhaustive since there are more occurrences) about the fact that there are a lot of exception logged. Those are surfaced through the telemetry and needs to get triaged. If those logs are not actionable I suggest to use the EXCLUDE_TELEMETRY marker

Good catch. These exceptions come from user-controlled data (malformed multipart parts, I/O failures reading temp files) and are not actionable from the agent side, so I've added EXCLUDE_TELEMETRY to all of them across the five modules. Applied in 4c96d0d.

The one exception is PartHelper.getAllParts a MethodHandle invocation failure there is instrumentation-internal and should reach telemetry, so it stays without the marker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: asm waf Application Security Management (WAF) type: enhancement Enhancements and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants