Skip to content

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

Open
jandro996 wants to merge 16 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 16 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 1777012226 1777017776
git_commit_sha 7c1b47b 3e9621e
release_version 1.62.0-SNAPSHOT~7c1b47b5d5 1.62.0-SNAPSHOT~3e9621e752
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1777019446 1777019446
ci_job_id 1627155825 1627155825
ci_pipeline_id 109482555 109482555
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-ctmfdr8n 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-ctmfdr8n 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 63 metrics, 8 unstable metrics.

Startup time reports for insecure-bank
gantt
    title insecure-bank - global startup overhead: candidate=1.62.0-SNAPSHOT~3e9621e752, baseline=1.62.0-SNAPSHOT~7c1b47b5d5

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.057 s) : 0, 1056828
Total [baseline] (8.848 s) : 0, 8848098
Agent [candidate] (1.06 s) : 0, 1059941
Total [candidate] (8.833 s) : 0, 8832757
section iast
Agent [baseline] (1.239 s) : 0, 1238866
Total [baseline] (9.533 s) : 0, 9532679
Agent [candidate] (1.241 s) : 0, 1241157
Total [candidate] (9.539 s) : 0, 9538778
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.057 s -
Agent iast 1.239 s 182.038 ms (17.2%)
Total tracing 8.848 s -
Total iast 9.533 s 684.581 ms (7.7%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.06 s -
Agent iast 1.241 s 181.217 ms (17.1%)
Total tracing 8.833 s -
Total iast 9.539 s 706.021 ms (8.0%)
gantt
    title insecure-bank - break down per module: candidate=1.62.0-SNAPSHOT~3e9621e752, baseline=1.62.0-SNAPSHOT~7c1b47b5d5

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.241 ms) : 0, 1241
crashtracking [candidate] (1.226 ms) : 0, 1226
BytebuddyAgent [baseline] (636.995 ms) : 0, 636995
BytebuddyAgent [candidate] (638.742 ms) : 0, 638742
AgentMeter [baseline] (29.285 ms) : 0, 29285
AgentMeter [candidate] (29.542 ms) : 0, 29542
GlobalTracer [baseline] (248.188 ms) : 0, 248188
GlobalTracer [candidate] (249.836 ms) : 0, 249836
AppSec [baseline] (32.327 ms) : 0, 32327
AppSec [candidate] (32.514 ms) : 0, 32514
Debugger [baseline] (59.662 ms) : 0, 59662
Debugger [candidate] (59.718 ms) : 0, 59718
Remote Config [baseline] (604.034 µs) : 0, 604
Remote Config [candidate] (597.983 µs) : 0, 598
Telemetry [baseline] (8.76 ms) : 0, 8760
Telemetry [candidate] (8.036 ms) : 0, 8036
Flare Poller [baseline] (3.623 ms) : 0, 3623
Flare Poller [candidate] (3.595 ms) : 0, 3595
section iast
crashtracking [baseline] (1.225 ms) : 0, 1225
crashtracking [candidate] (1.225 ms) : 0, 1225
BytebuddyAgent [baseline] (814.614 ms) : 0, 814614
BytebuddyAgent [candidate] (817.62 ms) : 0, 817620
AgentMeter [baseline] (11.56 ms) : 0, 11560
AgentMeter [candidate] (11.495 ms) : 0, 11495
GlobalTracer [baseline] (240.117 ms) : 0, 240117
GlobalTracer [candidate] (240.548 ms) : 0, 240548
AppSec [baseline] (29.686 ms) : 0, 29686
AppSec [candidate] (27.559 ms) : 0, 27559
Debugger [baseline] (64.384 ms) : 0, 64384
Debugger [candidate] (62.249 ms) : 0, 62249
Remote Config [baseline] (534.732 µs) : 0, 535
Remote Config [candidate] (521.719 µs) : 0, 522
Telemetry [baseline] (7.764 ms) : 0, 7764
Telemetry [candidate] (7.709 ms) : 0, 7709
Flare Poller [baseline] (3.505 ms) : 0, 3505
Flare Poller [candidate] (3.477 ms) : 0, 3477
IAST [baseline] (29.366 ms) : 0, 29366
IAST [candidate] (32.652 ms) : 0, 32652
Loading
Startup time reports for petclinic
gantt
    title petclinic - global startup overhead: candidate=1.62.0-SNAPSHOT~3e9621e752, baseline=1.62.0-SNAPSHOT~7c1b47b5d5

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.065 s) : 0, 1064846
Total [baseline] (11.09 s) : 0, 11090002
Agent [candidate] (1.065 s) : 0, 1064888
Total [candidate] (11.054 s) : 0, 11054387
section appsec
Agent [baseline] (1.263 s) : 0, 1262699
Total [baseline] (11.106 s) : 0, 11106452
Agent [candidate] (1.268 s) : 0, 1268270
Total [candidate] (11.094 s) : 0, 11093620
section iast
Agent [baseline] (1.234 s) : 0, 1233762
Total [baseline] (11.313 s) : 0, 11312792
Agent [candidate] (1.234 s) : 0, 1233914
Total [candidate] (11.295 s) : 0, 11294588
section profiling
Agent [baseline] (1.186 s) : 0, 1186352
Total [baseline] (11.129 s) : 0, 11129024
Agent [candidate] (1.188 s) : 0, 1187925
Total [candidate] (11.033 s) : 0, 11033294
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.065 s -
Agent appsec 1.263 s 197.853 ms (18.6%)
Agent iast 1.234 s 168.916 ms (15.9%)
Agent profiling 1.186 s 121.506 ms (11.4%)
Total tracing 11.09 s -
Total appsec 11.106 s 16.45 ms (0.1%)
Total iast 11.313 s 222.79 ms (2.0%)
Total profiling 11.129 s 39.022 ms (0.4%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.065 s -
Agent appsec 1.268 s 203.382 ms (19.1%)
Agent iast 1.234 s 169.026 ms (15.9%)
Agent profiling 1.188 s 123.037 ms (11.6%)
Total tracing 11.054 s -
Total appsec 11.094 s 39.233 ms (0.4%)
Total iast 11.295 s 240.201 ms (2.2%)
Total profiling 11.033 s -21.093 ms (-0.2%)
gantt
    title petclinic - break down per module: candidate=1.62.0-SNAPSHOT~3e9621e752, baseline=1.62.0-SNAPSHOT~7c1b47b5d5

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.23 ms) : 0, 1230
crashtracking [candidate] (1.228 ms) : 0, 1228
BytebuddyAgent [baseline] (640.182 ms) : 0, 640182
BytebuddyAgent [candidate] (639.892 ms) : 0, 639892
AgentMeter [baseline] (29.681 ms) : 0, 29681
AgentMeter [candidate] (29.596 ms) : 0, 29596
GlobalTracer [baseline] (250.833 ms) : 0, 250833
GlobalTracer [candidate] (250.756 ms) : 0, 250756
AppSec [baseline] (32.731 ms) : 0, 32731
AppSec [candidate] (32.518 ms) : 0, 32518
Debugger [baseline] (60.819 ms) : 0, 60819
Debugger [candidate] (60.753 ms) : 0, 60753
Remote Config [baseline] (607.062 µs) : 0, 607
Remote Config [candidate] (601.103 µs) : 0, 601
Telemetry [baseline] (8.108 ms) : 0, 8108
Telemetry [candidate] (8.93 ms) : 0, 8930
Flare Poller [baseline] (4.369 ms) : 0, 4369
Flare Poller [candidate] (4.408 ms) : 0, 4408
section appsec
crashtracking [baseline] (1.218 ms) : 0, 1218
crashtracking [candidate] (1.221 ms) : 0, 1221
BytebuddyAgent [baseline] (676.125 ms) : 0, 676125
BytebuddyAgent [candidate] (679.904 ms) : 0, 679904
AgentMeter [baseline] (12.259 ms) : 0, 12259
AgentMeter [candidate] (12.359 ms) : 0, 12359
GlobalTracer [baseline] (248.921 ms) : 0, 248921
GlobalTracer [candidate] (250.454 ms) : 0, 250454
AppSec [baseline] (186.027 ms) : 0, 186027
AppSec [candidate] (185.772 ms) : 0, 185772
Debugger [baseline] (65.69 ms) : 0, 65690
Debugger [candidate] (65.906 ms) : 0, 65906
Remote Config [baseline] (573.251 µs) : 0, 573
Remote Config [candidate] (586.559 µs) : 0, 587
Telemetry [baseline] (7.898 ms) : 0, 7898
Telemetry [candidate] (7.953 ms) : 0, 7953
Flare Poller [baseline] (3.417 ms) : 0, 3417
Flare Poller [candidate] (3.467 ms) : 0, 3467
IAST [baseline] (24.201 ms) : 0, 24201
IAST [candidate] (24.194 ms) : 0, 24194
section iast
crashtracking [baseline] (1.205 ms) : 0, 1205
crashtracking [candidate] (1.208 ms) : 0, 1208
BytebuddyAgent [baseline] (810.261 ms) : 0, 810261
BytebuddyAgent [candidate] (811.077 ms) : 0, 811077
AgentMeter [baseline] (11.342 ms) : 0, 11342
AgentMeter [candidate] (11.408 ms) : 0, 11408
GlobalTracer [baseline] (239.393 ms) : 0, 239393
GlobalTracer [candidate] (239.547 ms) : 0, 239547
AppSec [baseline] (28.338 ms) : 0, 28338
AppSec [candidate] (25.678 ms) : 0, 25678
Debugger [baseline] (66.079 ms) : 0, 66079
Debugger [candidate] (66.524 ms) : 0, 66524
Remote Config [baseline] (548.188 µs) : 0, 548
Remote Config [candidate] (523.414 µs) : 0, 523
Telemetry [baseline] (7.908 ms) : 0, 7908
Telemetry [candidate] (7.759 ms) : 0, 7759
Flare Poller [baseline] (3.536 ms) : 0, 3536
Flare Poller [candidate] (3.424 ms) : 0, 3424
IAST [baseline] (29.102 ms) : 0, 29102
IAST [candidate] (30.773 ms) : 0, 30773
section profiling
crashtracking [baseline] (1.17 ms) : 0, 1170
crashtracking [candidate] (1.182 ms) : 0, 1182
BytebuddyAgent [baseline] (692.255 ms) : 0, 692255
BytebuddyAgent [candidate] (694.878 ms) : 0, 694878
AgentMeter [baseline] (8.937 ms) : 0, 8937
AgentMeter [candidate] (8.987 ms) : 0, 8987
GlobalTracer [baseline] (207.673 ms) : 0, 207673
GlobalTracer [candidate] (207.7 ms) : 0, 207700
AppSec [baseline] (32.693 ms) : 0, 32693
AppSec [candidate] (32.504 ms) : 0, 32504
Debugger [baseline] (66.026 ms) : 0, 66026
Debugger [candidate] (65.308 ms) : 0, 65308
Remote Config [baseline] (570.526 µs) : 0, 571
Remote Config [candidate] (580.99 µs) : 0, 581
Telemetry [baseline] (7.896 ms) : 0, 7896
Telemetry [candidate] (7.781 ms) : 0, 7781
Flare Poller [baseline] (3.524 ms) : 0, 3524
Flare Poller [candidate] (3.518 ms) : 0, 3518
ProfilingAgent [baseline] (94.109 ms) : 0, 94109
ProfilingAgent [candidate] (93.635 ms) : 0, 93635
Profiling [baseline] (94.697 ms) : 0, 94697
Profiling [candidate] (94.205 ms) : 0, 94205
Loading

Load

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alejandro.gonzalez/APPSEC-61873-4-undertow-play
git_commit_date 1777012226 1777017776
git_commit_sha 7c1b47b 3e9621e
release_version 1.62.0-SNAPSHOT~7c1b47b5d5 1.62.0-SNAPSHOT~3e9621e752
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1777020031 1777020031
ci_job_id 1627155826 1627155826
ci_pipeline_id 109482555 109482555
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-g1ydpj6j 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-g1ydpj6j 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 4 performance improvements and 2 performance regressions! Performance is the same for 14 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:profiling:high_load better
[-188.674µs; -58.081µs] or [-10.313%; -3.175%]
unstable
[-1188.093µs; -333.514µs] or [-20.871%; -5.859%]
unstable
[+1.152op/s; +469.285op/s] or [+0.060%; +24.471%]
1.706ms 4.932ms 2152.969op/s 1.829ms 5.692ms 1917.750op/s
scenario:load:insecure-bank:iast_GLOBAL:high_load better
[-309.950µs; -201.392µs] or [-10.114%; -6.572%]
better
[-815.395µs; -312.412µs] or [-9.485%; -3.634%]
unstable
[-46.356op/s; +225.418op/s] or [-3.886%; +18.897%]
2.809ms 8.033ms 1282.406op/s 3.064ms 8.597ms 1192.875op/s
scenario:load:insecure-bank:iast:high_load worse
[+145.890µs; +243.288µs] or [+5.794%; +9.662%]
worse
[+305.742µs; +690.472µs] or [+4.187%; +9.456%]
unstable
[-243.975op/s; +42.975op/s] or [-17.142%; +3.020%]
2.713ms 7.800ms 1322.719op/s 2.518ms 7.302ms 1423.219op/s
scenario:load:petclinic:tracing:high_load unsure
[-486.644µs; -110.033µs] or [-2.788%; -0.630%]
better
[-1.499ms; -0.652ms] or [-5.168%; -2.248%]
unstable
[-20.331op/s; +31.394op/s] or [-7.793%; +12.034%]
17.154ms 27.924ms 266.406op/s 17.452ms 29.000ms 260.875op/s
Request duration reports for petclinic
gantt
    title petclinic - request duration [CI 0.99] : candidate=1.62.0-SNAPSHOT~3e9621e752, baseline=1.62.0-SNAPSHOT~7c1b47b5d5
    dateFormat X
    axisFormat %s
section baseline
no_agent (18.254 ms) : 18069, 18439
.   : milestone, 18254,
appsec (18.396 ms) : 18212, 18579
.   : milestone, 18396,
code_origins (17.708 ms) : 17534, 17882
.   : milestone, 17708,
iast (18.127 ms) : 17946, 18308
.   : milestone, 18127,
profiling (18.334 ms) : 18151, 18516
.   : milestone, 18334,
tracing (17.885 ms) : 17704, 18065
.   : milestone, 17885,
section candidate
no_agent (18.18 ms) : 17997, 18364
.   : milestone, 18180,
appsec (18.753 ms) : 18564, 18941
.   : milestone, 18753,
code_origins (17.718 ms) : 17544, 17891
.   : milestone, 17718,
iast (18.278 ms) : 18093, 18462
.   : milestone, 18278,
profiling (18.31 ms) : 18126, 18494
.   : milestone, 18310,
tracing (17.51 ms) : 17339, 17681
.   : milestone, 17510,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 18.254 ms [18.069 ms, 18.439 ms] -
appsec 18.396 ms [18.212 ms, 18.579 ms] 141.567 µs (0.8%)
code_origins 17.708 ms [17.534 ms, 17.882 ms] -546.008 µs (-3.0%)
iast 18.127 ms [17.946 ms, 18.308 ms] -127.33 µs (-0.7%)
profiling 18.334 ms [18.151 ms, 18.516 ms] 79.636 µs (0.4%)
tracing 17.885 ms [17.704 ms, 18.065 ms] -369.473 µs (-2.0%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 18.18 ms [17.997 ms, 18.364 ms] -
appsec 18.753 ms [18.564 ms, 18.941 ms] 572.108 µs (3.1%)
code_origins 17.718 ms [17.544 ms, 17.891 ms] -462.831 µs (-2.5%)
iast 18.278 ms [18.093 ms, 18.462 ms] 97.081 µs (0.5%)
profiling 18.31 ms [18.126 ms, 18.494 ms] 129.473 µs (0.7%)
tracing 17.51 ms [17.339 ms, 17.681 ms] -670.434 µs (-3.7%)
Request duration reports for insecure-bank
gantt
    title insecure-bank - request duration [CI 0.99] : candidate=1.62.0-SNAPSHOT~3e9621e752, baseline=1.62.0-SNAPSHOT~7c1b47b5d5
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.243 ms) : 1231, 1254
.   : milestone, 1243,
iast (3.213 ms) : 3172, 3254
.   : milestone, 3213,
iast_FULL (6.031 ms) : 5971, 6091
.   : milestone, 6031,
iast_GLOBAL (3.847 ms) : 3784, 3911
.   : milestone, 3847,
profiling (2.365 ms) : 2339, 2390
.   : milestone, 2365,
tracing (1.861 ms) : 1845, 1876
.   : milestone, 1861,
section candidate
no_agent (1.261 ms) : 1250, 1272
.   : milestone, 1261,
iast (3.465 ms) : 3416, 3514
.   : milestone, 3465,
iast_FULL (5.894 ms) : 5835, 5954
.   : milestone, 5894,
iast_GLOBAL (3.575 ms) : 3516, 3634
.   : milestone, 3575,
profiling (2.099 ms) : 2080, 2117
.   : milestone, 2099,
tracing (1.876 ms) : 1861, 1891
.   : milestone, 1876,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 1.243 ms [1.231 ms, 1.254 ms] -
iast 3.213 ms [3.172 ms, 3.254 ms] 1.97 ms (158.6%)
iast_FULL 6.031 ms [5.971 ms, 6.091 ms] 4.789 ms (385.4%)
iast_GLOBAL 3.847 ms [3.784 ms, 3.911 ms] 2.605 ms (209.6%)
profiling 2.365 ms [2.339 ms, 2.39 ms] 1.122 ms (90.3%)
tracing 1.861 ms [1.845 ms, 1.876 ms] 617.951 µs (49.7%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 1.261 ms [1.25 ms, 1.272 ms] -
iast 3.465 ms [3.416 ms, 3.514 ms] 2.204 ms (174.8%)
iast_FULL 5.894 ms [5.835 ms, 5.954 ms] 4.634 ms (367.5%)
iast_GLOBAL 3.575 ms [3.516 ms, 3.634 ms] 2.314 ms (183.5%)
profiling 2.099 ms [2.08 ms, 2.117 ms] 837.776 µs (66.4%)
tracing 1.876 ms [1.861 ms, 1.891 ms] 615.082 µs (48.8%)

Dacapo

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alejandro.gonzalez/APPSEC-61873-4-undertow-play
git_commit_date 1777012226 1777017776
git_commit_sha 7c1b47b 3e9621e
release_version 1.62.0-SNAPSHOT~7c1b47b5d5 1.62.0-SNAPSHOT~3e9621e752
See matching parameters
Baseline Candidate
application biojava biojava
ci_job_date 1777019896 1777019896
ci_job_id 1627155827 1627155827
ci_pipeline_id 109482555 109482555
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-2-y2qabzac 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-2-y2qabzac 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 10 metrics, 2 unstable metrics.

Execution time for biojava
gantt
    title biojava - execution time [CI 0.99] : candidate=1.62.0-SNAPSHOT~3e9621e752, baseline=1.62.0-SNAPSHOT~7c1b47b5d5
    dateFormat X
    axisFormat %s
section baseline
no_agent (15.528 s) : 15528000, 15528000
.   : milestone, 15528000,
appsec (14.873 s) : 14873000, 14873000
.   : milestone, 14873000,
iast (18.616 s) : 18616000, 18616000
.   : milestone, 18616000,
iast_GLOBAL (18.039 s) : 18039000, 18039000
.   : milestone, 18039000,
profiling (14.959 s) : 14959000, 14959000
.   : milestone, 14959000,
tracing (15.009 s) : 15009000, 15009000
.   : milestone, 15009000,
section candidate
no_agent (15.367 s) : 15367000, 15367000
.   : milestone, 15367000,
appsec (14.642 s) : 14642000, 14642000
.   : milestone, 14642000,
iast (18.204 s) : 18204000, 18204000
.   : milestone, 18204000,
iast_GLOBAL (17.991 s) : 17991000, 17991000
.   : milestone, 17991000,
profiling (15.138 s) : 15138000, 15138000
.   : milestone, 15138000,
tracing (15.172 s) : 15172000, 15172000
.   : milestone, 15172000,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 15.528 s [15.528 s, 15.528 s] -
appsec 14.873 s [14.873 s, 14.873 s] -655.0 ms (-4.2%)
iast 18.616 s [18.616 s, 18.616 s] 3.088 s (19.9%)
iast_GLOBAL 18.039 s [18.039 s, 18.039 s] 2.511 s (16.2%)
profiling 14.959 s [14.959 s, 14.959 s] -569.0 ms (-3.7%)
tracing 15.009 s [15.009 s, 15.009 s] -519.0 ms (-3.3%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 15.367 s [15.367 s, 15.367 s] -
appsec 14.642 s [14.642 s, 14.642 s] -725.0 ms (-4.7%)
iast 18.204 s [18.204 s, 18.204 s] 2.837 s (18.5%)
iast_GLOBAL 17.991 s [17.991 s, 17.991 s] 2.624 s (17.1%)
profiling 15.138 s [15.138 s, 15.138 s] -229.0 ms (-1.5%)
tracing 15.172 s [15.172 s, 15.172 s] -195.0 ms (-1.3%)
Execution time for tomcat
gantt
    title tomcat - execution time [CI 0.99] : candidate=1.62.0-SNAPSHOT~3e9621e752, baseline=1.62.0-SNAPSHOT~7c1b47b5d5
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.491 ms) : 1479, 1503
.   : milestone, 1491,
appsec (3.802 ms) : 3582, 4021
.   : milestone, 3802,
iast (2.278 ms) : 2208, 2347
.   : milestone, 2278,
iast_GLOBAL (2.323 ms) : 2253, 2393
.   : milestone, 2323,
profiling (2.513 ms) : 2289, 2737
.   : milestone, 2513,
tracing (2.09 ms) : 2036, 2144
.   : milestone, 2090,
section candidate
no_agent (1.495 ms) : 1483, 1506
.   : milestone, 1495,
appsec (3.837 ms) : 3612, 4062
.   : milestone, 3837,
iast (2.286 ms) : 2216, 2355
.   : milestone, 2286,
iast_GLOBAL (2.321 ms) : 2251, 2391
.   : milestone, 2321,
profiling (2.097 ms) : 2042, 2151
.   : milestone, 2097,
tracing (2.086 ms) : 2033, 2140
.   : milestone, 2086,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.491 ms [1.479 ms, 1.503 ms] -
appsec 3.802 ms [3.582 ms, 4.021 ms] 2.311 ms (155.0%)
iast 2.278 ms [2.208 ms, 2.347 ms] 786.816 µs (52.8%)
iast_GLOBAL 2.323 ms [2.253 ms, 2.393 ms] 832.001 µs (55.8%)
profiling 2.513 ms [2.289 ms, 2.737 ms] 1.022 ms (68.5%)
tracing 2.09 ms [2.036 ms, 2.144 ms] 598.853 µs (40.2%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.495 ms [1.483 ms, 1.506 ms] -
appsec 3.837 ms [3.612 ms, 4.062 ms] 2.343 ms (156.8%)
iast 2.286 ms [2.216 ms, 2.355 ms] 791.242 µs (52.9%)
iast_GLOBAL 2.321 ms [2.251 ms, 2.391 ms] 826.271 µs (55.3%)
profiling 2.097 ms [2.042 ms, 2.151 ms] 602.145 µs (40.3%)
tracing 2.086 ms [2.033 ms, 2.14 ms] 591.869 µs (39.6%)

…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.
@jandro996
Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

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

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