Skip to content

Add server.request.body.filenames AppSec address for Undertow and Play#11174

Open
jandro996 wants to merge 15 commits intomasterfrom
alejandro.gonzalez/APPSEC-61873-4-undertow-play
Open

Add server.request.body.filenames AppSec address for Undertow and Play#11174
jandro996 wants to merge 15 commits intomasterfrom
alejandro.gonzalez/APPSEC-61873-4-undertow-play

Conversation

@jandro996
Copy link
Copy Markdown
Member

@jandro996 jandro996 commented Apr 21, 2026

What Does This Do

Undertow (undertow-2.0, covers 2.0–2.3+)

  • MultiPartUploadHandlerInstrumentation: Extends the parseBlocking() exit advice to fire the requestFilesFilenames IG event alongside the existing requestBodyProcessed event. The two callbacks are evaluated independently — early return only when both are null, so deployments with filename-only WAF rules still work. The filenames callback is skipped when the body callback already triggered a block. tryCommitBlockingResponse() return value is now checked before assigning the thrown exception, consistent with Play behavior.
  • FormDataMap bug fix: Switched the text-field filter from !isFile() to getFileName() == null. In Undertow 2.2+, in-memory file uploads (below the size threshold) have isFile() == false even though they are file uploads — the old guard caused getValue() to be called on file parts, throwing IllegalStateException on every multipart request with small attachments. getFileName() == null correctly identifies text fields in all Undertow versions.

Play 2.5 / 2.6 (play-appsec-2.5, play-appsec-2.6)

  • BodyParserHelpers.handleMultipartFormData(): Adds handleMultipartFilenames() which iterates MultipartFormData.FilePart.filename() values and fires the requestFilesFilenames callback via executeFilenamesCallback() with full blocking support.
  • Scala 2.13 muzzle fix: MultipartFormData.files() returns scala.collection.Seq in Scala 2.11/2.12 but scala.collection.immutable.Seq in Scala 2.13 (Play 2.7+). A direct call embeds the return-type descriptor in bytecode; muzzle detects it as missing and disables the whole PlayBodyParsersInstrumentation for Play 2.7. The fix caches the Method in a static final MULTIPART_FILES_METHOD field initialized once at class load — no return-type descriptor in bytecode, zero reflection cost per request.

Motivation

Part of APPSEC-61873server.request.body.filenames implementation across server frameworks.

Depends on #10949 and #10973 (both merged into master).

Additional Notes

Static reflection pattern for Scala 2.13 compatibility: MultipartFormData.files() has a binary-incompatible return type between Scala 2.11/2.12 (scala.collection.Seq) and 2.13 (scala.collection.immutable.Seq). Rather than duplicating modules or restricting the muzzle version range, MULTIPART_FILES_METHOD is cached as a static final Method in a static {} initializer. The initializer runs once when the helper class is loaded into the application classloader (where the correct Play version is already present), so there is no per-request reflection cost and no return-type descriptor appears in the instrumentation bytecode. Method.invoke dispatches polymorphically, so the correct override is called regardless of the concrete MultipartFormData subclass.

Contributor Checklist

Jira ticket: APPSEC-61873

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.

- Undertow: extract filenames from FormData attachments in MultiPartUploadHandlerInstrumentation
- Play 2.5/2.6: extract filenames from MultipartFormData.files() in BodyParserHelpers

Both implementations fire the requestFilesFilenames() IG event and support
blocking on malicious filenames.
In undertow 2.2+, FormValueImpl.isFile() returns false for in-memory file uploads
(file size below fileSizeThreshold) because it checks fileItem.isInMemory(). Use
getFileName() to identify file uploads regardless of storage, which works across
all undertow versions. Also check the filenames callback before building the list
to avoid allocations on requests where the feature is inactive.
@jandro996 jandro996 added type: enhancement Enhancements and improvements comp: asm waf Application Security Management (WAF) labels Apr 21, 2026
@jandro996
Copy link
Copy Markdown
Member Author

@codex review

Copy link
Copy Markdown

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

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: f340ebfab9

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

…Undertow

Both callbacks are now fetched upfront; the method only returns early when both
are null. Previously an early return on requestBodyProcessed==null silently
skipped filename detection, breaking deployments with filename-only WAF rules.
@pr-commenter
Copy link
Copy Markdown

pr-commenter Bot commented Apr 21, 2026

Benchmarks

Startup

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alejandro.gonzalez/APPSEC-61873-4-undertow-play
git_commit_date 1776944677 1776952846
git_commit_sha d4d2069 43dc2fc
release_version 1.62.0-SNAPSHOT~d4d2069709 1.62.0-SNAPSHOT~43dc2fcc14
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1776954776 1776954776
ci_job_id 1624187457 1624187457
ci_pipeline_id 109306620 109306620
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-1-ulp9ea95 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-1-ulp9ea95 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
module Agent Agent
parent None None

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 60 metrics, 11 unstable metrics.

Startup time reports for petclinic
gantt
    title petclinic - global startup overhead: candidate=1.62.0-SNAPSHOT~43dc2fcc14, baseline=1.62.0-SNAPSHOT~d4d2069709

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.061 s) : 0, 1060687
Total [baseline] (11.078 s) : 0, 11078058
Agent [candidate] (1.063 s) : 0, 1062986
Total [candidate] (11.163 s) : 0, 11162926
section appsec
Agent [baseline] (1.264 s) : 0, 1264329
Total [baseline] (11.071 s) : 0, 11070568
Agent [candidate] (1.268 s) : 0, 1268457
Total [candidate] (11.245 s) : 0, 11244872
section iast
Agent [baseline] (1.242 s) : 0, 1241933
Total [baseline] (11.356 s) : 0, 11356214
Agent [candidate] (1.234 s) : 0, 1234342
Total [candidate] (11.344 s) : 0, 11343791
section profiling
Agent [baseline] (1.187 s) : 0, 1186802
Total [baseline] (11.033 s) : 0, 11032564
Agent [candidate] (1.187 s) : 0, 1187070
Total [candidate] (11.102 s) : 0, 11101696
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.061 s -
Agent appsec 1.264 s 203.642 ms (19.2%)
Agent iast 1.242 s 181.246 ms (17.1%)
Agent profiling 1.187 s 126.115 ms (11.9%)
Total tracing 11.078 s -
Total appsec 11.071 s -7.49 ms (-0.1%)
Total iast 11.356 s 278.156 ms (2.5%)
Total profiling 11.033 s -45.494 ms (-0.4%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.063 s -
Agent appsec 1.268 s 205.47 ms (19.3%)
Agent iast 1.234 s 171.356 ms (16.1%)
Agent profiling 1.187 s 124.083 ms (11.7%)
Total tracing 11.163 s -
Total appsec 11.245 s 81.946 ms (0.7%)
Total iast 11.344 s 180.865 ms (1.6%)
Total profiling 11.102 s -61.23 ms (-0.5%)
gantt
    title petclinic - break down per module: candidate=1.62.0-SNAPSHOT~43dc2fcc14, baseline=1.62.0-SNAPSHOT~d4d2069709

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.234 ms) : 0, 1234
crashtracking [candidate] (1.225 ms) : 0, 1225
BytebuddyAgent [baseline] (635.638 ms) : 0, 635638
BytebuddyAgent [candidate] (639.627 ms) : 0, 639627
AgentMeter [baseline] (29.591 ms) : 0, 29591
AgentMeter [candidate] (29.735 ms) : 0, 29735
GlobalTracer [baseline] (249.51 ms) : 0, 249510
GlobalTracer [candidate] (250.577 ms) : 0, 250577
AppSec [baseline] (32.341 ms) : 0, 32341
AppSec [candidate] (32.473 ms) : 0, 32473
Debugger [baseline] (59.879 ms) : 0, 59879
Debugger [candidate] (60.023 ms) : 0, 60023
Remote Config [baseline] (596.017 µs) : 0, 596
Remote Config [candidate] (595.128 µs) : 0, 595
Telemetry [baseline] (9.579 ms) : 0, 9579
Telemetry [candidate] (8.065 ms) : 0, 8065
Flare Poller [baseline] (5.899 ms) : 0, 5899
Flare Poller [candidate] (4.348 ms) : 0, 4348
section appsec
crashtracking [baseline] (1.239 ms) : 0, 1239
crashtracking [candidate] (1.241 ms) : 0, 1241
BytebuddyAgent [baseline] (676.661 ms) : 0, 676661
BytebuddyAgent [candidate] (678.366 ms) : 0, 678366
AgentMeter [baseline] (12.16 ms) : 0, 12160
AgentMeter [candidate] (12.205 ms) : 0, 12205
GlobalTracer [baseline] (249.523 ms) : 0, 249523
GlobalTracer [candidate] (250.52 ms) : 0, 250520
IAST [baseline] (24.199 ms) : 0, 24199
IAST [candidate] (24.337 ms) : 0, 24337
AppSec [baseline] (185.969 ms) : 0, 185969
AppSec [candidate] (187.926 ms) : 0, 187926
Debugger [baseline] (66.132 ms) : 0, 66132
Debugger [candidate] (65.333 ms) : 0, 65333
Remote Config [baseline] (578.49 µs) : 0, 578
Remote Config [candidate] (570.064 µs) : 0, 570
Telemetry [baseline] (7.919 ms) : 0, 7919
Telemetry [candidate] (7.955 ms) : 0, 7955
Flare Poller [baseline] (3.457 ms) : 0, 3457
Flare Poller [candidate] (3.446 ms) : 0, 3446
section iast
crashtracking [baseline] (1.261 ms) : 0, 1261
crashtracking [candidate] (1.232 ms) : 0, 1232
BytebuddyAgent [baseline] (815.78 ms) : 0, 815780
BytebuddyAgent [candidate] (810.776 ms) : 0, 810776
AgentMeter [baseline] (11.545 ms) : 0, 11545
AgentMeter [candidate] (11.419 ms) : 0, 11419
GlobalTracer [baseline] (240.939 ms) : 0, 240939
GlobalTracer [candidate] (239.669 ms) : 0, 239669
IAST [baseline] (29.331 ms) : 0, 29331
IAST [candidate] (29.205 ms) : 0, 29205
AppSec [baseline] (29.615 ms) : 0, 29615
AppSec [candidate] (29.412 ms) : 0, 29412
Debugger [baseline] (65.198 ms) : 0, 65198
Debugger [candidate] (64.782 ms) : 0, 64782
Remote Config [baseline] (547.111 µs) : 0, 547
Remote Config [candidate] (543.993 µs) : 0, 544
Telemetry [baseline] (7.792 ms) : 0, 7792
Telemetry [candidate] (7.764 ms) : 0, 7764
Flare Poller [baseline] (3.454 ms) : 0, 3454
Flare Poller [candidate] (3.396 ms) : 0, 3396
section profiling
crashtracking [baseline] (1.188 ms) : 0, 1188
crashtracking [candidate] (1.193 ms) : 0, 1193
BytebuddyAgent [baseline] (693.459 ms) : 0, 693459
BytebuddyAgent [candidate] (693.001 ms) : 0, 693001
AgentMeter [baseline] (8.975 ms) : 0, 8975
AgentMeter [candidate] (9.007 ms) : 0, 9007
GlobalTracer [baseline] (207.519 ms) : 0, 207519
GlobalTracer [candidate] (207.798 ms) : 0, 207798
AppSec [baseline] (32.565 ms) : 0, 32565
AppSec [candidate] (32.711 ms) : 0, 32711
Debugger [baseline] (65.643 ms) : 0, 65643
Debugger [candidate] (65.724 ms) : 0, 65724
Remote Config [baseline] (577.877 µs) : 0, 578
Remote Config [candidate] (577.55 µs) : 0, 578
Telemetry [baseline] (7.811 ms) : 0, 7811
Telemetry [candidate] (7.862 ms) : 0, 7862
Flare Poller [baseline] (3.501 ms) : 0, 3501
Flare Poller [candidate] (3.5 ms) : 0, 3500
ProfilingAgent [baseline] (93.977 ms) : 0, 93977
ProfilingAgent [candidate] (94.363 ms) : 0, 94363
Profiling [baseline] (94.536 ms) : 0, 94536
Profiling [candidate] (94.921 ms) : 0, 94921
Loading
Startup time reports for insecure-bank
gantt
    title insecure-bank - global startup overhead: candidate=1.62.0-SNAPSHOT~43dc2fcc14, baseline=1.62.0-SNAPSHOT~d4d2069709

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.056 s) : 0, 1055923
Total [baseline] (8.88 s) : 0, 8880287
Agent [candidate] (1.058 s) : 0, 1057820
Total [candidate] (8.898 s) : 0, 8897676
section iast
Agent [baseline] (1.234 s) : 0, 1233652
Total [baseline] (9.616 s) : 0, 9616036
Agent [candidate] (1.238 s) : 0, 1237898
Total [candidate] (9.62 s) : 0, 9619592
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.056 s -
Agent iast 1.234 s 177.729 ms (16.8%)
Total tracing 8.88 s -
Total iast 9.616 s 735.749 ms (8.3%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.058 s -
Agent iast 1.238 s 180.078 ms (17.0%)
Total tracing 8.898 s -
Total iast 9.62 s 721.916 ms (8.1%)
gantt
    title insecure-bank - break down per module: candidate=1.62.0-SNAPSHOT~43dc2fcc14, baseline=1.62.0-SNAPSHOT~d4d2069709

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.235 ms) : 0, 1235
crashtracking [candidate] (1.237 ms) : 0, 1237
BytebuddyAgent [baseline] (635.493 ms) : 0, 635493
BytebuddyAgent [candidate] (636.384 ms) : 0, 636384
AgentMeter [baseline] (29.572 ms) : 0, 29572
AgentMeter [candidate] (29.569 ms) : 0, 29569
GlobalTracer [baseline] (249.081 ms) : 0, 249081
GlobalTracer [candidate] (249.222 ms) : 0, 249222
AppSec [baseline] (32.2 ms) : 0, 32200
AppSec [candidate] (32.398 ms) : 0, 32398
Debugger [baseline] (59.052 ms) : 0, 59052
Debugger [candidate] (58.959 ms) : 0, 58959
Remote Config [baseline] (605.392 µs) : 0, 605
Remote Config [candidate] (602.19 µs) : 0, 602
Telemetry [baseline] (8.017 ms) : 0, 8017
Telemetry [candidate] (8.811 ms) : 0, 8811
Flare Poller [baseline] (4.344 ms) : 0, 4344
Flare Poller [candidate] (4.312 ms) : 0, 4312
section iast
crashtracking [baseline] (1.239 ms) : 0, 1239
crashtracking [candidate] (1.225 ms) : 0, 1225
BytebuddyAgent [baseline] (810.651 ms) : 0, 810651
BytebuddyAgent [candidate] (812.53 ms) : 0, 812530
AgentMeter [baseline] (11.39 ms) : 0, 11390
AgentMeter [candidate] (11.407 ms) : 0, 11407
GlobalTracer [baseline] (239.693 ms) : 0, 239693
GlobalTracer [candidate] (241.289 ms) : 0, 241289
IAST [baseline] (27.368 ms) : 0, 27368
IAST [candidate] (27.671 ms) : 0, 27671
AppSec [baseline] (28.662 ms) : 0, 28662
AppSec [candidate] (30.696 ms) : 0, 30696
Debugger [baseline] (66.677 ms) : 0, 66677
Debugger [candidate] (64.894 ms) : 0, 64894
Remote Config [baseline] (534.184 µs) : 0, 534
Remote Config [candidate] (552.107 µs) : 0, 552
Telemetry [baseline] (7.769 ms) : 0, 7769
Telemetry [candidate] (7.9 ms) : 0, 7900
Flare Poller [baseline] (3.479 ms) : 0, 3479
Flare Poller [candidate] (3.511 ms) : 0, 3511
Loading

Load

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alejandro.gonzalez/APPSEC-61873-4-undertow-play
git_commit_date 1776944677 1776952846
git_commit_sha d4d2069 43dc2fc
release_version 1.62.0-SNAPSHOT~d4d2069709 1.62.0-SNAPSHOT~43dc2fcc14
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1776955266 1776955266
ci_job_id 1624187459 1624187459
ci_pipeline_id 109306620 109306620
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-1-xy0wr6ge 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-1-xy0wr6ge 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Summary

Found 2 performance improvements and 0 performance regressions! Performance is the same for 18 metrics, 16 unstable metrics.

scenario Δ mean agg_http_req_duration_p50 Δ mean agg_http_req_duration_p95 Δ mean throughput candidate mean agg_http_req_duration_p50 candidate mean agg_http_req_duration_p95 candidate mean throughput baseline mean agg_http_req_duration_p50 baseline mean agg_http_req_duration_p95 baseline mean throughput
scenario:load:insecure-bank:iast_GLOBAL:high_load unsure
[-158.314µs; -48.572µs] or [-5.346%; -1.640%]
better
[-550.326µs; -173.990µs] or [-6.598%; -2.086%]
unstable
[-74.515op/s; +165.828op/s] or [-6.079%; +13.529%]
2.858ms 7.978ms 1271.344op/s 2.961ms 8.340ms 1225.688op/s
scenario:load:petclinic:code_origins:high_load better
[-1303.471µs; -440.522µs] or [-7.069%; -2.389%]
unsure
[-1690.728µs; -190.089µs] or [-5.684%; -0.639%]
unstable
[-14.026op/s; +35.214op/s] or [-5.633%; +14.142%]
17.568ms 28.803ms 259.594op/s 18.440ms 29.743ms 249.000op/s
Request duration reports for petclinic
gantt
    title petclinic - request duration [CI 0.99] : candidate=1.62.0-SNAPSHOT~43dc2fcc14, baseline=1.62.0-SNAPSHOT~d4d2069709
    dateFormat X
    axisFormat %s
section baseline
no_agent (18.14 ms) : 17954, 18327
.   : milestone, 18140,
appsec (19.395 ms) : 19202, 19589
.   : milestone, 19395,
code_origins (18.74 ms) : 18553, 18927
.   : milestone, 18740,
iast (17.887 ms) : 17710, 18064
.   : milestone, 17887,
profiling (18.348 ms) : 18164, 18533
.   : milestone, 18348,
tracing (17.832 ms) : 17656, 18008
.   : milestone, 17832,
section candidate
no_agent (18.058 ms) : 17875, 18240
.   : milestone, 18058,
appsec (19.138 ms) : 18945, 19332
.   : milestone, 19138,
code_origins (17.972 ms) : 17795, 18150
.   : milestone, 17972,
iast (17.989 ms) : 17806, 18172
.   : milestone, 17989,
profiling (18.128 ms) : 17948, 18307
.   : milestone, 18128,
tracing (17.841 ms) : 17666, 18017
.   : milestone, 17841,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 18.14 ms [17.954 ms, 18.327 ms] -
appsec 19.395 ms [19.202 ms, 19.589 ms] 1.255 ms (6.9%)
code_origins 18.74 ms [18.553 ms, 18.927 ms] 599.977 µs (3.3%)
iast 17.887 ms [17.71 ms, 18.064 ms] -253.636 µs (-1.4%)
profiling 18.348 ms [18.164 ms, 18.533 ms] 207.752 µs (1.1%)
tracing 17.832 ms [17.656 ms, 18.008 ms] -308.415 µs (-1.7%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 18.058 ms [17.875 ms, 18.24 ms] -
appsec 19.138 ms [18.945 ms, 19.332 ms] 1.081 ms (6.0%)
code_origins 17.972 ms [17.795 ms, 18.15 ms] -85.48 µs (-0.5%)
iast 17.989 ms [17.806 ms, 18.172 ms] -68.155 µs (-0.4%)
profiling 18.128 ms [17.948 ms, 18.307 ms] 70.098 µs (0.4%)
tracing 17.841 ms [17.666 ms, 18.017 ms] -216.389 µs (-1.2%)
Request duration reports for insecure-bank
gantt
    title insecure-bank - request duration [CI 0.99] : candidate=1.62.0-SNAPSHOT~43dc2fcc14, baseline=1.62.0-SNAPSHOT~d4d2069709
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.367 ms) : 1353, 1381
.   : milestone, 1367,
iast (3.511 ms) : 3459, 3563
.   : milestone, 3511,
iast_FULL (6.032 ms) : 5970, 6093
.   : milestone, 6032,
iast_GLOBAL (3.743 ms) : 3682, 3804
.   : milestone, 3743,
profiling (2.151 ms) : 2129, 2172
.   : milestone, 2151,
tracing (1.847 ms) : 1831, 1863
.   : milestone, 1847,
section candidate
no_agent (1.273 ms) : 1261, 1285
.   : milestone, 1273,
iast (3.407 ms) : 3358, 3457
.   : milestone, 3407,
iast_FULL (6.053 ms) : 5991, 6114
.   : milestone, 6053,
iast_GLOBAL (3.606 ms) : 3547, 3665
.   : milestone, 3606,
profiling (2.204 ms) : 2184, 2224
.   : milestone, 2204,
tracing (1.869 ms) : 1854, 1884
.   : milestone, 1869,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 1.367 ms [1.353 ms, 1.381 ms] -
iast 3.511 ms [3.459 ms, 3.563 ms] 2.144 ms (156.8%)
iast_FULL 6.032 ms [5.97 ms, 6.093 ms] 4.664 ms (341.2%)
iast_GLOBAL 3.743 ms [3.682 ms, 3.804 ms] 2.375 ms (173.7%)
profiling 2.151 ms [2.129 ms, 2.172 ms] 783.437 µs (57.3%)
tracing 1.847 ms [1.831 ms, 1.863 ms] 479.38 µs (35.1%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 1.273 ms [1.261 ms, 1.285 ms] -
iast 3.407 ms [3.358 ms, 3.457 ms] 2.134 ms (167.7%)
iast_FULL 6.053 ms [5.991 ms, 6.114 ms] 4.78 ms (375.4%)
iast_GLOBAL 3.606 ms [3.547 ms, 3.665 ms] 2.333 ms (183.3%)
profiling 2.204 ms [2.184 ms, 2.224 ms] 930.828 µs (73.1%)
tracing 1.869 ms [1.854 ms, 1.884 ms] 596.183 µs (46.8%)

Dacapo

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alejandro.gonzalez/APPSEC-61873-4-undertow-play
git_commit_date 1776944677 1776952846
git_commit_sha d4d2069 43dc2fc
release_version 1.62.0-SNAPSHOT~d4d2069709 1.62.0-SNAPSHOT~43dc2fcc14
See matching parameters
Baseline Candidate
application biojava biojava
ci_job_date 1776954957 1776954957
ci_job_id 1624187461 1624187461
ci_pipeline_id 109306620 109306620
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-0-5iavzxbb 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-0-5iavzxbb 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 11 metrics, 1 unstable metrics.

Execution time for biojava
gantt
    title biojava - execution time [CI 0.99] : candidate=1.62.0-SNAPSHOT~43dc2fcc14, baseline=1.62.0-SNAPSHOT~d4d2069709
    dateFormat X
    axisFormat %s
section baseline
no_agent (15.013 s) : 15013000, 15013000
.   : milestone, 15013000,
appsec (14.642 s) : 14642000, 14642000
.   : milestone, 14642000,
iast (18.247 s) : 18247000, 18247000
.   : milestone, 18247000,
iast_GLOBAL (17.752 s) : 17752000, 17752000
.   : milestone, 17752000,
profiling (15.55 s) : 15550000, 15550000
.   : milestone, 15550000,
tracing (14.74 s) : 14740000, 14740000
.   : milestone, 14740000,
section candidate
no_agent (15.019 s) : 15019000, 15019000
.   : milestone, 15019000,
appsec (14.974 s) : 14974000, 14974000
.   : milestone, 14974000,
iast (18.248 s) : 18248000, 18248000
.   : milestone, 18248000,
iast_GLOBAL (18.085 s) : 18085000, 18085000
.   : milestone, 18085000,
profiling (15.606 s) : 15606000, 15606000
.   : milestone, 15606000,
tracing (14.834 s) : 14834000, 14834000
.   : milestone, 14834000,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 15.013 s [15.013 s, 15.013 s] -
appsec 14.642 s [14.642 s, 14.642 s] -371.0 ms (-2.5%)
iast 18.247 s [18.247 s, 18.247 s] 3.234 s (21.5%)
iast_GLOBAL 17.752 s [17.752 s, 17.752 s] 2.739 s (18.2%)
profiling 15.55 s [15.55 s, 15.55 s] 537.0 ms (3.6%)
tracing 14.74 s [14.74 s, 14.74 s] -273.0 ms (-1.8%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 15.019 s [15.019 s, 15.019 s] -
appsec 14.974 s [14.974 s, 14.974 s] -45.0 ms (-0.3%)
iast 18.248 s [18.248 s, 18.248 s] 3.229 s (21.5%)
iast_GLOBAL 18.085 s [18.085 s, 18.085 s] 3.066 s (20.4%)
profiling 15.606 s [15.606 s, 15.606 s] 587.0 ms (3.9%)
tracing 14.834 s [14.834 s, 14.834 s] -185.0 ms (-1.2%)
Execution time for tomcat
gantt
    title tomcat - execution time [CI 0.99] : candidate=1.62.0-SNAPSHOT~43dc2fcc14, baseline=1.62.0-SNAPSHOT~d4d2069709
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.487 ms) : 1476, 1499
.   : milestone, 1487,
appsec (3.829 ms) : 3607, 4051
.   : milestone, 3829,
iast (2.273 ms) : 2204, 2343
.   : milestone, 2273,
iast_GLOBAL (2.311 ms) : 2241, 2381
.   : milestone, 2311,
profiling (2.095 ms) : 2040, 2150
.   : milestone, 2095,
tracing (2.075 ms) : 2022, 2129
.   : milestone, 2075,
section candidate
no_agent (1.481 ms) : 1470, 1493
.   : milestone, 1481,
appsec (3.817 ms) : 3594, 4039
.   : milestone, 3817,
iast (2.269 ms) : 2200, 2338
.   : milestone, 2269,
iast_GLOBAL (2.313 ms) : 2243, 2383
.   : milestone, 2313,
profiling (2.084 ms) : 2030, 2139
.   : milestone, 2084,
tracing (2.069 ms) : 2016, 2123
.   : milestone, 2069,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.487 ms [1.476 ms, 1.499 ms] -
appsec 3.829 ms [3.607 ms, 4.051 ms] 2.342 ms (157.5%)
iast 2.273 ms [2.204 ms, 2.343 ms] 786.152 µs (52.9%)
iast_GLOBAL 2.311 ms [2.241 ms, 2.381 ms] 823.632 µs (55.4%)
profiling 2.095 ms [2.04 ms, 2.15 ms] 608.06 µs (40.9%)
tracing 2.075 ms [2.022 ms, 2.129 ms] 587.848 µs (39.5%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.481 ms [1.47 ms, 1.493 ms] -
appsec 3.817 ms [3.594 ms, 4.039 ms] 2.335 ms (157.6%)
iast 2.269 ms [2.2 ms, 2.338 ms] 787.599 µs (53.2%)
iast_GLOBAL 2.313 ms [2.243 ms, 2.383 ms] 832.051 µs (56.2%)
profiling 2.084 ms [2.03 ms, 2.139 ms] 603.058 µs (40.7%)
tracing 2.069 ms [2.016 ms, 2.123 ms] 588.082 µs (39.7%)

…port

Use reflection to invoke MultipartFormData.files() so the bytecode does not
embed a hard reference to the Scala 2.11/2.12 return type
(Lscala/collection/Seq;). In Scala 2.13 (Play 2.7+) the method returns
scala.collection.immutable.Seq, causing muzzle to disable the entire
PlayBodyParsersInstrumentation and breaking all body-parsing features.

Also enable testBodyFilenames() in Play 2.5/2.6/2.7 test suites.
Avoids a redundant WAF evaluation when the request was already blocked by
the requestBodyProcessed callback. The filenamesCb is now only invoked when
t == null (no block committed yet), and the inner t == null guard is removed
since it is now guaranteed by the outer condition.
@jandro996 jandro996 force-pushed the alejandro.gonzalez/APPSEC-61873-4-undertow-play branch from c991aee to b3a4e2a Compare April 23, 2026 12:17
@jandro996
Copy link
Copy Markdown
Member Author

@codex review

@jandro996 jandro996 changed the title Add server.request.body.filenames support for Undertow and Play Add server.request.body.filenames AppSec address for Undertow and Play Apr 23, 2026
@jandro996 jandro996 marked this pull request as ready for review April 23, 2026 12:35
@jandro996 jandro996 requested review from a team as code owners April 23, 2026 12:35
Add getCharset(), getFileItem(), isFileItem(), and isBigField() stubs
to the anonymous FormData.FormValue in addInMemoryFileValue(). These
abstract methods were added in undertow 2.2.x and caused compilation
failure when the latestDepForkedTest resolved the latest 2.2.x release.
…ferences

FormData.FormValue gained getCharset(), getFileItem(), isFileItem(), and
isBigField() in undertow 2.2.x. A static anonymous class can't implement
all versions simultaneously. Using a Proxy resolves the interface at
runtime, so the test compiles against undertow 2.0 and runs correctly
against the latest 2.2.x dependency.
@jandro996
Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

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

… tests

AbstractPlayServerTest is shared by both play-2.6 (no AppSec) and
play-appsec-2.6 tests. Setting testBodyFilenames=true there caused the
plain play-2.6 tests to check the request.body.filenames tag, which is
never set without the AppSec instrumentation.

Move the override into PlayServerTest and PlayAsyncServerTest in
play-appsec-2.6, which are the modules where the instrumentation is active.
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.

1 participant