Skip to content

Add server.request.body.filenames support for Jetty#10988

Draft
jandro996 wants to merge 24 commits intomasterfrom
alejandro.gonzalez/APPSEC-61873-3
Draft

Add server.request.body.filenames support for Jetty#10988
jandro996 wants to merge 24 commits intomasterfrom
alejandro.gonzalez/APPSEC-61873-3

Conversation

@jandro996
Copy link
Copy Markdown
Member

@jandro996 jandro996 commented Mar 27, 2026

What Does This Do

Jetty parses multipart bodies through two code paths depending on how the application accesses the request:

  • getParameterMap()extractContentParameters() → internal getParts(MultiMap)
  • Direct getParts() call from user code

Both paths are instrumented to fire requestFilesFilenames. Guards on internal state fields (_contentParameters, _multiParts, _multiPartInputStream) prevent double-firing.

Module Why modified / added
jetty-appsec-7.0 Added GetFilenamesAdvice for getParts(). No extractContentParameters in 7.x so only one path exists.
jetty-appsec-8.1.3 Added both advice classes. Servlet 2.x has no getSubmittedFileName() so filenames are parsed from the Content-Disposition header. Logic extracted to MultipartHelper with unit tests.
jetty-appsec-9.2 Added both advice classes. Uses Part.getSubmittedFileName() (Servlet 3.1). Logic extracted to MultipartHelper with unit tests.
jetty-appsec-9.3 Narrowed from [9.3, 12) to [9.3, 9.4). Removed reflection (getDeclaredField / Method.invoke) by restricting scope to only 9.3.x, where _multiPartInputStream is the correct field. MultipartHelper added with unit tests.
jetty-appsec-9.4 (new) Covers [9.4, 11.0) — javax.servlet, uses _multiParts field (introduced in 9.4). Previously handled by 9.3 via reflection. MultipartHelper with unit tests.
jetty-appsec-11.0 (new) Covers [11.0, 12.0) — jakarta.servlet (first Jetty version to drop javax). Previously handled by 9.3 via reflection. MultipartHelper with unit tests.
  • Server test modules (jetty-server-9.3/9.4.21/10.0/11.0/12.0) updated to reference the correct appsec module per Jetty version range.

Motivation

Additional Notes

Depends on #10973 (merged).
Part of Jira ticket: APPSEC-61873server.request.body.filenames implementation across server frameworks.

Contributor Checklist

@jandro996 jandro996 added comp: asm waf Application Security Management (WAF) type: enhancement Enhancements and improvements labels Mar 27, 2026
@pr-commenter
Copy link
Copy Markdown

pr-commenter bot commented Mar 27, 2026

Benchmarks

Startup

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alejandro.gonzalez/APPSEC-61873-3
git_commit_date 1776156083 1776155693
git_commit_sha f89a0b26cc 08f15a2
release_version 1.62.0-SNAPSHOT~9f89a0b26cc 1.61.0-SNAPSHOT~08f15a2f4c
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1776157378 1776157378
ci_job_id 1592438316 1592438316
ci_pipeline_id 107528819 107528819
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-5f0npaab 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-5f0npaab 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 61 metrics, 10 unstable metrics.

Startup time reports for petclinic
gantt
    title petclinic - global startup overhead: candidate=1.61.0-SNAPSHOT~08f15a2f4c, baseline=1.62.0-SNAPSHOT~9f89a0b26cc

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.065 s) : 0, 1065446
Total [baseline] (11.065 s) : 0, 11064813
Agent [candidate] (1.06 s) : 0, 1059572
Total [candidate] (11.02 s) : 0, 11020112
section appsec
Agent [baseline] (1.249 s) : 0, 1249227
Total [baseline] (11.138 s) : 0, 11138312
Agent [candidate] (1.248 s) : 0, 1247866
Total [candidate] (11.244 s) : 0, 11243764
section iast
Agent [baseline] (1.234 s) : 0, 1234040
Total [baseline] (11.319 s) : 0, 11318546
Agent [candidate] (1.227 s) : 0, 1226650
Total [candidate] (11.233 s) : 0, 11232771
section profiling
Agent [baseline] (1.188 s) : 0, 1188430
Total [baseline] (11.121 s) : 0, 11120621
Agent [candidate] (1.184 s) : 0, 1183632
Total [candidate] (11.119 s) : 0, 11118654
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.065 s -
Agent appsec 1.249 s 183.781 ms (17.2%)
Agent iast 1.234 s 168.594 ms (15.8%)
Agent profiling 1.188 s 122.984 ms (11.5%)
Total tracing 11.065 s -
Total appsec 11.138 s 73.5 ms (0.7%)
Total iast 11.319 s 253.733 ms (2.3%)
Total profiling 11.121 s 55.808 ms (0.5%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.06 s -
Agent appsec 1.248 s 188.295 ms (17.8%)
Agent iast 1.227 s 167.079 ms (15.8%)
Agent profiling 1.184 s 124.061 ms (11.7%)
Total tracing 11.02 s -
Total appsec 11.244 s 223.652 ms (2.0%)
Total iast 11.233 s 212.659 ms (1.9%)
Total profiling 11.119 s 98.542 ms (0.9%)
gantt
    title petclinic - break down per module: candidate=1.61.0-SNAPSHOT~08f15a2f4c, baseline=1.62.0-SNAPSHOT~9f89a0b26cc

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.231 ms) : 0, 1231
crashtracking [candidate] (1.213 ms) : 0, 1213
BytebuddyAgent [baseline] (636.776 ms) : 0, 636776
BytebuddyAgent [candidate] (636.415 ms) : 0, 636415
AgentMeter [baseline] (29.619 ms) : 0, 29619
AgentMeter [candidate] (29.541 ms) : 0, 29541
GlobalTracer [baseline] (250.535 ms) : 0, 250535
GlobalTracer [candidate] (250.21 ms) : 0, 250210
AppSec [baseline] (32.249 ms) : 0, 32249
AppSec [candidate] (32.153 ms) : 0, 32153
Debugger [baseline] (60.792 ms) : 0, 60792
Debugger [candidate] (60.004 ms) : 0, 60004
Remote Config [baseline] (610.292 µs) : 0, 610
Remote Config [candidate] (615.677 µs) : 0, 616
Telemetry [baseline] (8.219 ms) : 0, 8219
Telemetry [candidate] (8.136 ms) : 0, 8136
Flare Poller [baseline] (9.165 ms) : 0, 9165
Flare Poller [candidate] (5.106 ms) : 0, 5106
section appsec
crashtracking [baseline] (1.223 ms) : 0, 1223
crashtracking [candidate] (1.212 ms) : 0, 1212
BytebuddyAgent [baseline] (663.087 ms) : 0, 663087
BytebuddyAgent [candidate] (662.539 ms) : 0, 662539
AgentMeter [baseline] (12.079 ms) : 0, 12079
AgentMeter [candidate] (11.986 ms) : 0, 11986
GlobalTracer [baseline] (249.416 ms) : 0, 249416
GlobalTracer [candidate] (248.449 ms) : 0, 248449
IAST [baseline] (24.558 ms) : 0, 24558
IAST [candidate] (24.613 ms) : 0, 24613
AppSec [baseline] (183.911 ms) : 0, 183911
AppSec [candidate] (184.045 ms) : 0, 184045
Debugger [baseline] (65.835 ms) : 0, 65835
Debugger [candidate] (65.312 ms) : 0, 65312
Remote Config [baseline] (603.059 µs) : 0, 603
Remote Config [candidate] (598.926 µs) : 0, 599
Telemetry [baseline] (8.634 ms) : 0, 8634
Telemetry [candidate] (9.257 ms) : 0, 9257
Flare Poller [baseline] (3.535 ms) : 0, 3535
Flare Poller [candidate] (3.572 ms) : 0, 3572
section iast
crashtracking [baseline] (1.229 ms) : 0, 1229
crashtracking [candidate] (1.23 ms) : 0, 1230
BytebuddyAgent [baseline] (808.444 ms) : 0, 808444
BytebuddyAgent [candidate] (802.82 ms) : 0, 802820
AgentMeter [baseline] (11.476 ms) : 0, 11476
AgentMeter [candidate] (11.491 ms) : 0, 11491
GlobalTracer [baseline] (240.71 ms) : 0, 240710
GlobalTracer [candidate] (239.77 ms) : 0, 239770
IAST [baseline] (25.953 ms) : 0, 25953
IAST [candidate] (25.782 ms) : 0, 25782
AppSec [baseline] (31.12 ms) : 0, 31120
AppSec [candidate] (31.86 ms) : 0, 31860
Debugger [baseline] (60.554 ms) : 0, 60554
Debugger [candidate] (64.348 ms) : 0, 64348
Remote Config [baseline] (539.909 µs) : 0, 540
Remote Config [candidate] (536.807 µs) : 0, 537
Telemetry [baseline] (13.887 ms) : 0, 13887
Telemetry [candidate] (9.269 ms) : 0, 9269
Flare Poller [baseline] (3.51 ms) : 0, 3510
Flare Poller [candidate] (3.442 ms) : 0, 3442
section profiling
crashtracking [baseline] (1.195 ms) : 0, 1195
crashtracking [candidate] (1.171 ms) : 0, 1171
BytebuddyAgent [baseline] (695.645 ms) : 0, 695645
BytebuddyAgent [candidate] (692.383 ms) : 0, 692383
AgentMeter [baseline] (9.16 ms) : 0, 9160
AgentMeter [candidate] (9.102 ms) : 0, 9102
GlobalTracer [baseline] (207.784 ms) : 0, 207784
GlobalTracer [candidate] (206.543 ms) : 0, 206543
AppSec [baseline] (32.376 ms) : 0, 32376
AppSec [candidate] (32.437 ms) : 0, 32437
Debugger [baseline] (65.206 ms) : 0, 65206
Debugger [candidate] (65.448 ms) : 0, 65448
Remote Config [baseline] (564.615 µs) : 0, 565
Remote Config [candidate] (566.036 µs) : 0, 566
Telemetry [baseline] (7.864 ms) : 0, 7864
Telemetry [candidate] (7.842 ms) : 0, 7842
Flare Poller [baseline] (3.574 ms) : 0, 3574
Flare Poller [candidate] (3.552 ms) : 0, 3552
ProfilingAgent [baseline] (93.511 ms) : 0, 93511
ProfilingAgent [candidate] (93.515 ms) : 0, 93515
Profiling [baseline] (94.078 ms) : 0, 94078
Profiling [candidate] (94.078 ms) : 0, 94078
Loading
Startup time reports for insecure-bank
gantt
    title insecure-bank - global startup overhead: candidate=1.61.0-SNAPSHOT~08f15a2f4c, baseline=1.62.0-SNAPSHOT~9f89a0b26cc

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.061 s) : 0, 1061185
Total [baseline] (8.877 s) : 0, 8876617
Agent [candidate] (1.057 s) : 0, 1057094
Total [candidate] (8.839 s) : 0, 8839098
section iast
Agent [baseline] (1.232 s) : 0, 1231826
Total [baseline] (9.608 s) : 0, 9608265
Agent [candidate] (1.22 s) : 0, 1219592
Total [candidate] (9.564 s) : 0, 9564451
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.061 s -
Agent iast 1.232 s 170.641 ms (16.1%)
Total tracing 8.877 s -
Total iast 9.608 s 731.649 ms (8.2%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.057 s -
Agent iast 1.22 s 162.498 ms (15.4%)
Total tracing 8.839 s -
Total iast 9.564 s 725.353 ms (8.2%)
gantt
    title insecure-bank - break down per module: candidate=1.61.0-SNAPSHOT~08f15a2f4c, baseline=1.62.0-SNAPSHOT~9f89a0b26cc

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.234 ms) : 0, 1234
crashtracking [candidate] (1.222 ms) : 0, 1222
BytebuddyAgent [baseline] (635.293 ms) : 0, 635293
BytebuddyAgent [candidate] (635.794 ms) : 0, 635794
AgentMeter [baseline] (29.553 ms) : 0, 29553
AgentMeter [candidate] (29.304 ms) : 0, 29304
GlobalTracer [baseline] (249.195 ms) : 0, 249195
GlobalTracer [candidate] (250.685 ms) : 0, 250685
AppSec [baseline] (32.005 ms) : 0, 32005
AppSec [candidate] (32.22 ms) : 0, 32220
Debugger [baseline] (59.077 ms) : 0, 59077
Debugger [candidate] (59.432 ms) : 0, 59432
Remote Config [baseline] (597.909 µs) : 0, 598
Remote Config [candidate] (605.25 µs) : 0, 605
Telemetry [baseline] (8.104 ms) : 0, 8104
Telemetry [candidate] (8.122 ms) : 0, 8122
Flare Poller [baseline] (9.907 ms) : 0, 9907
Flare Poller [candidate] (3.54 ms) : 0, 3540
section iast
crashtracking [baseline] (1.246 ms) : 0, 1246
crashtracking [candidate] (1.228 ms) : 0, 1228
BytebuddyAgent [baseline] (807.132 ms) : 0, 807132
BytebuddyAgent [candidate] (798.309 ms) : 0, 798309
AgentMeter [baseline] (11.394 ms) : 0, 11394
AgentMeter [candidate] (11.31 ms) : 0, 11310
GlobalTracer [baseline] (240.882 ms) : 0, 240882
GlobalTracer [candidate] (238.276 ms) : 0, 238276
IAST [baseline] (26.04 ms) : 0, 26040
IAST [candidate] (26.514 ms) : 0, 26514
AppSec [baseline] (31.21 ms) : 0, 31210
AppSec [candidate] (31.001 ms) : 0, 31001
Debugger [baseline] (60.584 ms) : 0, 60584
Debugger [candidate] (63.597 ms) : 0, 63597
Remote Config [baseline] (541.159 µs) : 0, 541
Remote Config [candidate] (534.129 µs) : 0, 534
Telemetry [baseline] (12.784 ms) : 0, 12784
Telemetry [candidate] (9.303 ms) : 0, 9303
Flare Poller [baseline] (3.558 ms) : 0, 3558
Flare Poller [candidate] (3.46 ms) : 0, 3460
Loading

Load

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alejandro.gonzalez/APPSEC-61873-3
git_commit_date 1776156130 1776155693
git_commit_sha f89a0b26cc 08f15a2
release_version 1.62.0-SNAPSHOT~9f89a0b26cc 1.61.0-SNAPSHOT~08f15a2f4c
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1776157899 1776157899
ci_job_id 1592438318 1592438318
ci_pipeline_id 107528819 107528819
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-3-lgu8ssnq 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-3-lgu8ssnq 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 1 performance improvements and 2 performance regressions! Performance is the same for 18 metrics, 15 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 worse
[+68.526µs; +243.690µs] or [+2.394%; +8.514%]
unsure
[+132.496µs; +590.238µs] or [+1.655%; +7.372%]
unstable
[-203.091op/s; +76.716op/s] or [-15.997%; +6.043%]
3.018ms 8.367ms 1206.375op/s 2.862ms 8.006ms 1269.562op/s
scenario:load:insecure-bank:iast:high_load worse
[+88.859µs; +152.303µs] or [+3.515%; +6.025%]
same
[-10.324µs; +367.534µs] or [-0.138%; +4.903%]
unstable
[-204.635op/s; +100.948op/s] or [-14.593%; +7.199%]
2.648ms 7.675ms 1350.469op/s 2.528ms 7.496ms 1402.312op/s
scenario:load:petclinic:appsec:high_load better
[-896.118µs; -394.610µs] or [-4.726%; -2.081%]
same
[-1032.928µs; +82.770µs] or [-3.407%; +0.273%]
unstable
[-21.530op/s; +34.280op/s] or [-8.844%; +14.082%]
18.318ms 29.841ms 249.812op/s 18.963ms 30.317ms 243.438op/s
Request duration reports for petclinic
gantt
    title petclinic - request duration [CI 0.99] : candidate=1.61.0-SNAPSHOT~08f15a2f4c, baseline=1.62.0-SNAPSHOT~9f89a0b26cc
    dateFormat X
    axisFormat %s
section baseline
no_agent (17.87 ms) : 17693, 18048
.   : milestone, 17870,
appsec (19.177 ms) : 18985, 19369
.   : milestone, 19177,
code_origins (17.855 ms) : 17680, 18030
.   : milestone, 17855,
iast (17.73 ms) : 17557, 17903
.   : milestone, 17730,
profiling (18.497 ms) : 18313, 18681
.   : milestone, 18497,
tracing (17.84 ms) : 17665, 18016
.   : milestone, 17840,
section candidate
no_agent (17.91 ms) : 17728, 18092
.   : milestone, 17910,
appsec (18.682 ms) : 18496, 18868
.   : milestone, 18682,
code_origins (17.89 ms) : 17713, 18067
.   : milestone, 17890,
iast (18.045 ms) : 17866, 18224
.   : milestone, 18045,
profiling (18.439 ms) : 18255, 18622
.   : milestone, 18439,
tracing (17.9 ms) : 17727, 18074
.   : milestone, 17900,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 17.87 ms [17.693 ms, 18.048 ms] -
appsec 19.177 ms [18.985 ms, 19.369 ms] 1.307 ms (7.3%)
code_origins 17.855 ms [17.68 ms, 18.03 ms] -15.719 µs (-0.1%)
iast 17.73 ms [17.557 ms, 17.903 ms] -140.368 µs (-0.8%)
profiling 18.497 ms [18.313 ms, 18.681 ms] 626.164 µs (3.5%)
tracing 17.84 ms [17.665 ms, 18.016 ms] -30.102 µs (-0.2%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 17.91 ms [17.728 ms, 18.092 ms] -
appsec 18.682 ms [18.496 ms, 18.868 ms] 772.237 µs (4.3%)
code_origins 17.89 ms [17.713 ms, 18.067 ms] -19.708 µs (-0.1%)
iast 18.045 ms [17.866 ms, 18.224 ms] 135.285 µs (0.8%)
profiling 18.439 ms [18.255 ms, 18.622 ms] 529.103 µs (3.0%)
tracing 17.9 ms [17.727 ms, 18.074 ms] -9.572 µs (-0.1%)
Request duration reports for insecure-bank
gantt
    title insecure-bank - request duration [CI 0.99] : candidate=1.61.0-SNAPSHOT~08f15a2f4c, baseline=1.62.0-SNAPSHOT~9f89a0b26cc
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.226 ms) : 1214, 1237
.   : milestone, 1226,
iast (3.263 ms) : 3216, 3310
.   : milestone, 3263,
iast_FULL (5.995 ms) : 5934, 6055
.   : milestone, 5995,
iast_GLOBAL (3.612 ms) : 3552, 3673
.   : milestone, 3612,
profiling (2.093 ms) : 2076, 2111
.   : milestone, 2093,
tracing (1.924 ms) : 1905, 1942
.   : milestone, 1924,
section candidate
no_agent (1.25 ms) : 1238, 1263
.   : milestone, 1250,
iast (3.39 ms) : 3343, 3438
.   : milestone, 3390,
iast_FULL (6.034 ms) : 5972, 6095
.   : milestone, 6034,
iast_GLOBAL (3.805 ms) : 3744, 3865
.   : milestone, 3805,
profiling (2.08 ms) : 2062, 2098
.   : milestone, 2080,
tracing (1.865 ms) : 1850, 1879
.   : milestone, 1865,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 1.226 ms [1.214 ms, 1.237 ms] -
iast 3.263 ms [3.216 ms, 3.31 ms] 2.037 ms (166.2%)
iast_FULL 5.995 ms [5.934 ms, 6.055 ms] 4.769 ms (389.2%)
iast_GLOBAL 3.612 ms [3.552 ms, 3.673 ms] 2.387 ms (194.8%)
profiling 2.093 ms [2.076 ms, 2.111 ms] 867.637 µs (70.8%)
tracing 1.924 ms [1.905 ms, 1.942 ms] 698.143 µs (57.0%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 1.25 ms [1.238 ms, 1.263 ms] -
iast 3.39 ms [3.343 ms, 3.438 ms] 2.14 ms (171.2%)
iast_FULL 6.034 ms [5.972 ms, 6.095 ms] 4.783 ms (382.5%)
iast_GLOBAL 3.805 ms [3.744 ms, 3.865 ms] 2.554 ms (204.3%)
profiling 2.08 ms [2.062 ms, 2.098 ms] 829.253 µs (66.3%)
tracing 1.865 ms [1.85 ms, 1.879 ms] 614.241 µs (49.1%)

Dacapo

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master alejandro.gonzalez/APPSEC-61873-3
git_commit_date 1776156083 1776155693
git_commit_sha f89a0b26cc 08f15a2
release_version 1.62.0-SNAPSHOT~9f89a0b26cc 1.61.0-SNAPSHOT~08f15a2f4c
See matching parameters
Baseline Candidate
application biojava biojava
ci_job_date 1776157597 1776157597
ci_job_id 1592438319 1592438319
ci_pipeline_id 107528819 107528819
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-4mumicjo 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-4mumicjo 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.61.0-SNAPSHOT~08f15a2f4c, baseline=1.62.0-SNAPSHOT~9f89a0b26cc
    dateFormat X
    axisFormat %s
section baseline
no_agent (14.773 s) : 14773000, 14773000
.   : milestone, 14773000,
appsec (14.941 s) : 14941000, 14941000
.   : milestone, 14941000,
iast (18.616 s) : 18616000, 18616000
.   : milestone, 18616000,
iast_GLOBAL (18.345 s) : 18345000, 18345000
.   : milestone, 18345000,
profiling (15.1 s) : 15100000, 15100000
.   : milestone, 15100000,
tracing (14.918 s) : 14918000, 14918000
.   : milestone, 14918000,
section candidate
no_agent (15.479 s) : 15479000, 15479000
.   : milestone, 15479000,
appsec (14.701 s) : 14701000, 14701000
.   : milestone, 14701000,
iast (18.465 s) : 18465000, 18465000
.   : milestone, 18465000,
iast_GLOBAL (18.029 s) : 18029000, 18029000
.   : milestone, 18029000,
profiling (15.384 s) : 15384000, 15384000
.   : milestone, 15384000,
tracing (14.852 s) : 14852000, 14852000
.   : milestone, 14852000,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 14.773 s [14.773 s, 14.773 s] -
appsec 14.941 s [14.941 s, 14.941 s] 168.0 ms (1.1%)
iast 18.616 s [18.616 s, 18.616 s] 3.843 s (26.0%)
iast_GLOBAL 18.345 s [18.345 s, 18.345 s] 3.572 s (24.2%)
profiling 15.1 s [15.1 s, 15.1 s] 327.0 ms (2.2%)
tracing 14.918 s [14.918 s, 14.918 s] 145.0 ms (1.0%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 15.479 s [15.479 s, 15.479 s] -
appsec 14.701 s [14.701 s, 14.701 s] -778.0 ms (-5.0%)
iast 18.465 s [18.465 s, 18.465 s] 2.986 s (19.3%)
iast_GLOBAL 18.029 s [18.029 s, 18.029 s] 2.55 s (16.5%)
profiling 15.384 s [15.384 s, 15.384 s] -95.0 ms (-0.6%)
tracing 14.852 s [14.852 s, 14.852 s] -627.0 ms (-4.1%)
Execution time for tomcat
gantt
    title tomcat - execution time [CI 0.99] : candidate=1.61.0-SNAPSHOT~08f15a2f4c, baseline=1.62.0-SNAPSHOT~9f89a0b26cc
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.495 ms) : 1483, 1506
.   : milestone, 1495,
appsec (3.86 ms) : 3637, 4083
.   : milestone, 3860,
iast (2.281 ms) : 2212, 2350
.   : milestone, 2281,
iast_GLOBAL (2.324 ms) : 2255, 2394
.   : milestone, 2324,
profiling (2.108 ms) : 2053, 2163
.   : milestone, 2108,
tracing (2.088 ms) : 2035, 2142
.   : milestone, 2088,
section candidate
no_agent (1.497 ms) : 1485, 1509
.   : milestone, 1497,
appsec (3.743 ms) : 3529, 3957
.   : milestone, 3743,
iast (2.286 ms) : 2216, 2355
.   : milestone, 2286,
iast_GLOBAL (2.331 ms) : 2261, 2401
.   : milestone, 2331,
profiling (2.106 ms) : 2051, 2161
.   : milestone, 2106,
tracing (2.09 ms) : 2036, 2143
.   : milestone, 2090,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.495 ms [1.483 ms, 1.506 ms] -
appsec 3.86 ms [3.637 ms, 4.083 ms] 2.365 ms (158.2%)
iast 2.281 ms [2.212 ms, 2.35 ms] 786.426 µs (52.6%)
iast_GLOBAL 2.324 ms [2.255 ms, 2.394 ms] 829.63 µs (55.5%)
profiling 2.108 ms [2.053 ms, 2.163 ms] 613.005 µs (41.0%)
tracing 2.088 ms [2.035 ms, 2.142 ms] 593.682 µs (39.7%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.497 ms [1.485 ms, 1.509 ms] -
appsec 3.743 ms [3.529 ms, 3.957 ms] 2.246 ms (150.1%)
iast 2.286 ms [2.216 ms, 2.355 ms] 789.028 µs (52.7%)
iast_GLOBAL 2.331 ms [2.261 ms, 2.401 ms] 834.306 µs (55.7%)
profiling 2.106 ms [2.051 ms, 2.161 ms] 609.258 µs (40.7%)
tracing 2.09 ms [2.036 ms, 2.143 ms] 592.796 µs (39.6%)

@jandro996 jandro996 force-pushed the alejandro.gonzalez/APPSEC-61873-3 branch from e3d4073 to e2d5ed0 Compare April 6, 2026 08:02
Add GetFilenamesAdvice to all three Jetty AppSec modules to collect
uploaded file names from multipart requests and fire the
requestFilesFilenames() IG callback:

- jetty-appsec-8.1.3: intercepts getParts() return value; includes
  Content-Disposition header fallback for Servlet 3.0 (Jetty 9.0)
  where getSubmittedFileName() is not available
- jetty-appsec-9.2: intercepts no-arg getParts() for Servlet 3.1+
- jetty-appsec-9.3: same, applies to Jetty 9.3, 10, 11

Enable testBodyFilenames() in Jetty 9.x, 10 and 11 server tests.
@jandro996 jandro996 force-pushed the alejandro.gonzalez/APPSEC-61873-3 branch from f2998c3 to 629f074 Compare April 6, 2026 10:50
@jandro996 jandro996 marked this pull request as ready for review April 6, 2026 13:08
@jandro996 jandro996 requested a review from a team as a code owner April 6, 2026 13:08
}
}
// Fallback: parse filename from Content-Disposition header (Servlet 3.0)
if (name == null) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shouldn't this be outside of the main parts loop?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed. Restructured into two separate loops chosen once before iteration: if getSubmittedFileName != null (Servlet 3.1+) iterate using that method; otherwise iterate parsing the Content-Disposition header (Servlet 3.0 fallback). No per-part branching inside the loop.

transformer.applyAdvice(
named("extractContentParameters").and(takesArguments(0)).or(named("getParts")),
getClass().getName() + "$ExtractContentParametersAdvice");
transformer.applyAdvice(named("getParts"), getClass().getName() + "$GetFilenamesAdvice");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as before

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed. GetFilenamesAdvice now has a call-depth guard (CallDepthThreadLocalMap with Collection.class) to avoid double-firing when getParts() internally calls getParts(MultiMap)

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

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

@jandro996 jandro996 force-pushed the alejandro.gonzalez/APPSEC-61873-3 branch 2 times, most recently from ecf65c5 to eae08aa Compare April 6, 2026 14:13
…MultiMap) path

- jetty-appsec-9.3: add call-depth guard (Collection.class) to GetFilenamesAdvice
  to prevent double callback invocation when getParts() calls getParts(MultiMap) internally
- jetty-appsec-9.2: extend GetFilenamesAdvice matcher to all getParts overloads
  (not just no-arg) to cover getParameter*()/getParameterMap() code paths,
  guarded with same call-depth mechanism to avoid double-firing
@jandro996 jandro996 force-pushed the alejandro.gonzalez/APPSEC-61873-3 branch 2 times, most recently from 3ab9ff7 to 77ec572 Compare April 7, 2026 07:33
@jandro996 jandro996 enabled auto-merge April 7, 2026 08:52
@jandro996 jandro996 force-pushed the alejandro.gonzalez/APPSEC-61873-3 branch from 2e72584 to d37e03e Compare April 7, 2026 09:23
@jandro996 jandro996 disabled auto-merge April 7, 2026 09:42
@jandro996 jandro996 marked this pull request as draft April 7, 2026 09:48
@jandro996 jandro996 force-pushed the alejandro.gonzalez/APPSEC-61873-3 branch from d37e03e to d8a92f8 Compare April 7, 2026 09:52
- Add BODY_MULTIPART_REPEATED case to TestServlet3 (javax) so Jetty 9.x/10.x
  test modules can exercise the repeated getParts() scenario
- Enable testBodyFilenamesCalledOnce() for Jetty 9.0, 9.0.4, 9.3, 9.4.21, and 10.0
…vice path

- New BODY_MULTIPART_COMBINED endpoint: calls getParameterMap() first (triggers
  GetFilenamesFromMultiPartAdvice via extractContentParameters -> getParts(MultiMap)),
  then getParts() explicitly (GetFilenamesAdvice must not double-fire since
  _contentParameters is already set)
- New test 'file upload filenames called once via parameter map' verifies the
  callback fires exactly once across both advice paths
- Enabled in Jetty 9.0, 9.0.4, 9.3, 9.4.21, 10.0 and 11.0
…eplaces _contentParameters as the getParts() cache

In Jetty 9.3, getParts(MultiMap) sets _contentParameters, so the map==null guard prevents
re-firing on repeated getParts() calls. In Jetty 9.4+, getParts() delegates to getParts(null)
and caches the result in _multiParts instead, leaving _contentParameters null on every call.
Add _multiParts==null as an additional guard (optional=true handles Jetty 9.3 where the
field does not exist).
In Jetty 8.x/9.0, _multiPartInputStream is null only on the first getParts() call.
Add OnMethodEnter guard to skip the WAF callback on subsequent calls which return
the cached multipart result.
@advice.FieldValue(optional=true) is not supported in ByteBuddy 1.11.22.
Replace it with @Advice.This + inline reflection to detect whether getParts()
has already been called on this request:

- Jetty 9.4+: checks _multiParts (set after first getParts() call)
- Jetty 9.3.x: falls back to _multiPartInputStream (the cache field in 9.3.x,
  where _multiParts does not exist and _contentParameters is only set by the
  getParameterMap() → extractContentParameters() path, not by getParts())

Covers all forkedTest and latestDepForkedTest suites for Jetty 9.0–11.
jandro996 added a commit to DataDog/system-tests that referenced this pull request Apr 9, 2026
Jetty multipart file upload instrumentation fixed in
DataDog/dd-trace-java#10988 (Jetty 8.1.3, 9.3–11).
jandro996 added 11 commits April 9, 2026 16:00
…t 3.1+ branch

Jetty 8 implements only Servlet 3.0, so getSubmittedFileName() is never
present on the Part objects. The reflection probe (try { getMethod("getSubmittedFileName") })
and the Servlet 3.1+ code path were dead code. Remove them and always
parse filenames from the Content-Disposition header directly.
Type @Advice.Return as Collection<Part> so the loop variable
can be Part directly, eliminating the (Part) cast on each iteration.
Move the filename extraction logic from GetFilenamesAdvice into a
new MultipartHelper helper class so it can be unit tested in isolation.
Add 12 Spock test cases covering quoted/unquoted filenames, empty
values, whitespace, null input, and edge cases.
…unit tests

Move the getSubmittedFileName() loop from GetFilenamesAdvice into a new
MultipartHelper helper class (injected via helperClassNames) so it can be
unit tested in isolation. Add 8 Spock test cases covering null/empty
collections, null/empty filenames, multiple parts, and special characters.
Eliminates all reflection from the multipart filename instrumentation by
creating version-specific modules with compile-time type safety:

- jetty-appsec-9.3 [9.3,9.4): javax.servlet, uses _multiPartInputStream field
- jetty-appsec-9.4 [9.4,11.0): javax.servlet, uses _multiParts field
- jetty-appsec-11.0 [11.0,12.0): jakarta.servlet, uses _multiParts field

Each module uses muzzle references as version discriminators instead of
runtime reflection, and delegates filename extraction to a testable
MultipartHelper class with 8 Spock unit tests each.

Server test modules updated to reference the correct appsec module per
Jetty version range.
- Add Jetty8LatestDepForkedTest: runs against Jetty 8.x (latestDepForkedTest
  task) and enables testBodyMultipart/testBodyFilenames coverage. Gated by
  'test.dd.filenames' system property so it is skipped when running against
  Jetty 7.6.
- Add testCompileOnly dep on org.eclipse.jetty.orbit:javax.servlet so
  MultipartConfigElement compiles without pulling in the excluded
  javax.servlet:javax.servlet-api artifact.
- Fix ParameterCollector.put to accept (Object, Object) and cast internally:
  Jetty 8.x MultiMap.add uses (Object, Object) descriptor while Jetty 9.x
  uses (String, Object), so the ASM bytecode visitor was silently skipping
  all form field captures on Jetty 8.
- Update GetPartsMethodVisitor to match both (String,Object) and (Object,Object)
  MultiMap.add descriptors and emit the INVOKEINTERFACE with (Object, Object).
_multiPartInputStream was replaced by _multiParts in Jetty 9.4.10.v20180503.
Early 9.4.x versions (9.4.0–9.4.9) still use _multiPartInputStream like 9.3.x,
so extend jetty-appsec-9.3 to cover [9.3, 9.4.10) and narrow jetty-appsec-9.4
to [9.4.10, 11.0). The classLoaderMatcher in jetty-appsec-9.4 (checking for
_multiParts) now correctly matches only versions >= 9.4.10.
…–11.x

The _multiParts field type changes multiple times across Jetty versions,
making a single typed muzzle reference insufficient. Replace the ASM-based
classLoaderMatcher with clean module splits using typed muzzle references:

- jetty-appsec-9.4   [9.4.10, 10.0):   _multiParts: MultiParts
                                         _queryEncoding: String (excludes 10.x)
- jetty-appsec-10.0  [10.0,  10.0.10): _multiParts: MultiPartFormInputStream
- jetty-appsec-10.0.10 [10.0.10, 11.0): _multiParts: MultiParts
                                          _queryEncoding: Charset (excludes 9.4.x)
- jetty-appsec-11.0  [11.0,  11.0.10): _multiParts: MultiPartFormInputStream
- jetty-appsec-11.0.10 [11.0.10, 12.0): _multiParts: MultiParts

All six modules pass muzzle with assertInverse = true.
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.

2 participants