Add server.request.body.filenames support for Akka HTTP, Grizzly, and Spring Boot#11173
Add server.request.body.filenames support for Akka HTTP, Grizzly, and Spring Boot#11173
Conversation
Extract filenames from Multipart.FormData.BodyPart.Strict using getFilename() in handleMultipartStrictFormData() and fire the requestFilesFilenames() IG event. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Enable the filename upload test for: Spring Boot, Grizzly, Play 2.5/2.6, and Akka HTTP test variants (with appropriate false overrides for sync and version-constrained cases). Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…eldMultiMap path - Jersey 2.0/3.0 (MultiPartReaderServerSideInstrumentation): extract filenames from FormDataBodyPart.getContentDisposition().getFileName() and fire requestFilesFilenames callback after requestBodyProcessed. Grizzly uses Jersey's multipart reader. - Akka HTTP 10.0 handleStrictFormData: the formFieldMultiMap path goes through StrictFormCompanionInstrumentation → handleStrictFormData, not through handleMultipartStrictFormData. Added filename extraction from Multipart$FormData$BodyPart$Strict.getFilename() and fires requestFilesFilenames callback with blocking support for this path.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 89592b09a8
ℹ️ 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".
BenchmarksStartupParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 62 metrics, 9 unstable metrics. Startup time reports for petclinicgantt
title petclinic - global startup overhead: candidate=1.62.0-SNAPSHOT~9aac562f91, baseline=1.62.0-SNAPSHOT~081af53226
dateFormat X
axisFormat %s
section tracing
Agent [baseline] (1.067 s) : 0, 1067243
Total [baseline] (11.126 s) : 0, 11126035
Agent [candidate] (1.058 s) : 0, 1058328
Total [candidate] (11.184 s) : 0, 11183770
section appsec
Agent [baseline] (1.249 s) : 0, 1249099
Total [baseline] (10.975 s) : 0, 10974815
Agent [candidate] (1.254 s) : 0, 1254446
Total [candidate] (11.131 s) : 0, 11130642
section iast
Agent [baseline] (1.226 s) : 0, 1225609
Total [baseline] (11.319 s) : 0, 11318985
Agent [candidate] (1.241 s) : 0, 1241491
Total [candidate] (11.328 s) : 0, 11328187
section profiling
Agent [baseline] (1.189 s) : 0, 1188925
Total [baseline] (11.036 s) : 0, 11035787
Agent [candidate] (1.188 s) : 0, 1187676
Total [candidate] (11.074 s) : 0, 11073694
gantt
title petclinic - break down per module: candidate=1.62.0-SNAPSHOT~9aac562f91, baseline=1.62.0-SNAPSHOT~081af53226
dateFormat X
axisFormat %s
section tracing
crashtracking [baseline] (1.243 ms) : 0, 1243
crashtracking [candidate] (1.226 ms) : 0, 1226
BytebuddyAgent [baseline] (636.785 ms) : 0, 636785
BytebuddyAgent [candidate] (632.966 ms) : 0, 632966
AgentMeter [baseline] (30.114 ms) : 0, 30114
AgentMeter [candidate] (29.578 ms) : 0, 29578
GlobalTracer [baseline] (252.128 ms) : 0, 252128
GlobalTracer [candidate] (249.224 ms) : 0, 249224
AppSec [baseline] (33.09 ms) : 0, 33090
AppSec [candidate] (32.337 ms) : 0, 32337
Debugger [baseline] (61.109 ms) : 0, 61109
Debugger [candidate] (59.873 ms) : 0, 59873
Remote Config [baseline] (632.243 µs) : 0, 632
Remote Config [candidate] (587.775 µs) : 0, 588
Telemetry [baseline] (8.262 ms) : 0, 8262
Telemetry [candidate] (7.983 ms) : 0, 7983
Flare Poller [baseline] (7.617 ms) : 0, 7617
Flare Poller [candidate] (8.28 ms) : 0, 8280
section appsec
crashtracking [baseline] (1.251 ms) : 0, 1251
crashtracking [candidate] (1.235 ms) : 0, 1235
BytebuddyAgent [baseline] (661.682 ms) : 0, 661682
BytebuddyAgent [candidate] (666.167 ms) : 0, 666167
AgentMeter [baseline] (12.272 ms) : 0, 12272
AgentMeter [candidate] (12.293 ms) : 0, 12293
GlobalTracer [baseline] (248.929 ms) : 0, 248929
GlobalTracer [candidate] (249.238 ms) : 0, 249238
AppSec [baseline] (185.196 ms) : 0, 185196
AppSec [candidate] (185.839 ms) : 0, 185839
Debugger [baseline] (66.007 ms) : 0, 66007
Debugger [candidate] (66.317 ms) : 0, 66317
Remote Config [baseline] (610.229 µs) : 0, 610
Remote Config [candidate] (601.932 µs) : 0, 602
Telemetry [baseline] (8.486 ms) : 0, 8486
Telemetry [candidate] (8.392 ms) : 0, 8392
Flare Poller [baseline] (3.571 ms) : 0, 3571
Flare Poller [candidate] (3.514 ms) : 0, 3514
IAST [baseline] (24.488 ms) : 0, 24488
IAST [candidate] (24.436 ms) : 0, 24436
section iast
crashtracking [baseline] (1.233 ms) : 0, 1233
crashtracking [candidate] (1.238 ms) : 0, 1238
BytebuddyAgent [baseline] (801.701 ms) : 0, 801701
BytebuddyAgent [candidate] (813.533 ms) : 0, 813533
AgentMeter [baseline] (11.616 ms) : 0, 11616
AgentMeter [candidate] (11.879 ms) : 0, 11879
GlobalTracer [baseline] (239.102 ms) : 0, 239102
GlobalTracer [candidate] (241.906 ms) : 0, 241906
AppSec [baseline] (32.15 ms) : 0, 32150
AppSec [candidate] (32.065 ms) : 0, 32065
Debugger [baseline] (64.319 ms) : 0, 64319
Debugger [candidate] (63.857 ms) : 0, 63857
Remote Config [baseline] (537.508 µs) : 0, 538
Remote Config [candidate] (544.014 µs) : 0, 544
Telemetry [baseline] (9.349 ms) : 0, 9349
Telemetry [candidate] (9.412 ms) : 0, 9412
Flare Poller [baseline] (3.59 ms) : 0, 3590
Flare Poller [candidate] (3.67 ms) : 0, 3670
IAST [baseline] (25.866 ms) : 0, 25866
IAST [candidate] (26.827 ms) : 0, 26827
section profiling
ProfilingAgent [baseline] (94.278 ms) : 0, 94278
ProfilingAgent [candidate] (94.706 ms) : 0, 94706
crashtracking [baseline] (1.202 ms) : 0, 1202
crashtracking [candidate] (1.193 ms) : 0, 1193
BytebuddyAgent [baseline] (693.79 ms) : 0, 693790
BytebuddyAgent [candidate] (693.119 ms) : 0, 693119
AgentMeter [baseline] (9.282 ms) : 0, 9282
AgentMeter [candidate] (9.205 ms) : 0, 9205
GlobalTracer [baseline] (207.599 ms) : 0, 207599
GlobalTracer [candidate] (207.346 ms) : 0, 207346
AppSec [baseline] (32.786 ms) : 0, 32786
AppSec [candidate] (32.834 ms) : 0, 32834
Debugger [baseline] (66.218 ms) : 0, 66218
Debugger [candidate] (65.742 ms) : 0, 65742
Remote Config [baseline] (587.155 µs) : 0, 587
Remote Config [candidate] (575.152 µs) : 0, 575
Telemetry [baseline] (7.829 ms) : 0, 7829
Telemetry [candidate] (7.826 ms) : 0, 7826
Flare Poller [baseline] (3.556 ms) : 0, 3556
Flare Poller [candidate] (3.629 ms) : 0, 3629
Profiling [baseline] (94.837 ms) : 0, 94837
Profiling [candidate] (95.279 ms) : 0, 95279
Startup time reports for insecure-bankgantt
title insecure-bank - global startup overhead: candidate=1.62.0-SNAPSHOT~9aac562f91, baseline=1.62.0-SNAPSHOT~081af53226
dateFormat X
axisFormat %s
section tracing
Agent [baseline] (1.059 s) : 0, 1059287
Total [baseline] (8.904 s) : 0, 8903653
Agent [candidate] (1.057 s) : 0, 1057272
Total [candidate] (8.848 s) : 0, 8847759
section iast
Agent [baseline] (1.235 s) : 0, 1235097
Total [baseline] (9.578 s) : 0, 9578171
Agent [candidate] (1.223 s) : 0, 1223198
Total [candidate] (9.607 s) : 0, 9607242
gantt
title insecure-bank - break down per module: candidate=1.62.0-SNAPSHOT~9aac562f91, baseline=1.62.0-SNAPSHOT~081af53226
dateFormat X
axisFormat %s
section tracing
crashtracking [baseline] (1.237 ms) : 0, 1237
crashtracking [candidate] (1.23 ms) : 0, 1230
BytebuddyAgent [baseline] (633.979 ms) : 0, 633979
BytebuddyAgent [candidate] (633.138 ms) : 0, 633138
AgentMeter [baseline] (29.62 ms) : 0, 29620
AgentMeter [candidate] (29.556 ms) : 0, 29556
GlobalTracer [baseline] (249.827 ms) : 0, 249827
GlobalTracer [candidate] (248.92 ms) : 0, 248920
AppSec [baseline] (32.725 ms) : 0, 32725
AppSec [candidate] (32.341 ms) : 0, 32341
Debugger [baseline] (59.613 ms) : 0, 59613
Debugger [candidate] (59.075 ms) : 0, 59075
Remote Config [baseline] (616.2 µs) : 0, 616
Remote Config [candidate] (584.497 µs) : 0, 584
Telemetry [baseline] (8.093 ms) : 0, 8093
Telemetry [candidate] (7.973 ms) : 0, 7973
Flare Poller [baseline] (7.417 ms) : 0, 7417
Flare Poller [candidate] (8.218 ms) : 0, 8218
section iast
crashtracking [baseline] (1.27 ms) : 0, 1270
crashtracking [candidate] (1.246 ms) : 0, 1246
BytebuddyAgent [baseline] (808.88 ms) : 0, 808880
BytebuddyAgent [candidate] (801.042 ms) : 0, 801042
AgentMeter [baseline] (11.689 ms) : 0, 11689
AgentMeter [candidate] (11.554 ms) : 0, 11554
GlobalTracer [baseline] (240.876 ms) : 0, 240876
GlobalTracer [candidate] (239.134 ms) : 0, 239134
IAST [baseline] (26.041 ms) : 0, 26041
IAST [candidate] (25.743 ms) : 0, 25743
AppSec [baseline] (29.896 ms) : 0, 29896
AppSec [candidate] (29.534 ms) : 0, 29534
Debugger [baseline] (66.585 ms) : 0, 66585
Debugger [candidate] (65.511 ms) : 0, 65511
Remote Config [baseline] (530.101 µs) : 0, 530
Remote Config [candidate] (531.176 µs) : 0, 531
Telemetry [baseline] (9.313 ms) : 0, 9313
Telemetry [candidate] (9.264 ms) : 0, 9264
Flare Poller [baseline] (3.606 ms) : 0, 3606
Flare Poller [candidate] (3.549 ms) : 0, 3549
LoadParameters
See matching parameters
SummaryFound 2 performance improvements and 0 performance regressions! Performance is the same for 16 metrics, 18 unstable metrics.
Request duration reports for insecure-bankgantt
title insecure-bank - request duration [CI 0.99] : candidate=1.62.0-SNAPSHOT~9aac562f91, baseline=1.62.0-SNAPSHOT~081af53226
dateFormat X
axisFormat %s
section baseline
no_agent (1.226 ms) : 1214, 1238
. : milestone, 1226,
iast (3.288 ms) : 3239, 3337
. : milestone, 3288,
iast_FULL (6.207 ms) : 6143, 6271
. : milestone, 6207,
iast_GLOBAL (3.715 ms) : 3656, 3775
. : milestone, 3715,
profiling (2.257 ms) : 2235, 2280
. : milestone, 2257,
tracing (1.958 ms) : 1941, 1974
. : milestone, 1958,
section candidate
no_agent (1.236 ms) : 1224, 1247
. : milestone, 1236,
iast (3.205 ms) : 3163, 3248
. : milestone, 3205,
iast_FULL (6.002 ms) : 5940, 6063
. : milestone, 6002,
iast_GLOBAL (3.573 ms) : 3515, 3632
. : milestone, 3573,
profiling (2.228 ms) : 2203, 2253
. : milestone, 2228,
tracing (1.891 ms) : 1875, 1907
. : milestone, 1891,
Request duration reports for petclinicgantt
title petclinic - request duration [CI 0.99] : candidate=1.62.0-SNAPSHOT~9aac562f91, baseline=1.62.0-SNAPSHOT~081af53226
dateFormat X
axisFormat %s
section baseline
no_agent (19.283 ms) : 19085, 19482
. : milestone, 19283,
appsec (19.574 ms) : 19375, 19773
. : milestone, 19574,
code_origins (18.084 ms) : 17903, 18265
. : milestone, 18084,
iast (17.826 ms) : 17650, 18003
. : milestone, 17826,
profiling (18.362 ms) : 18182, 18543
. : milestone, 18362,
tracing (18.882 ms) : 18690, 19074
. : milestone, 18882,
section candidate
no_agent (18.316 ms) : 18130, 18502
. : milestone, 18316,
appsec (19.782 ms) : 19583, 19982
. : milestone, 19782,
code_origins (17.994 ms) : 17818, 18171
. : milestone, 17994,
iast (18.007 ms) : 17831, 18183
. : milestone, 18007,
profiling (18.427 ms) : 18245, 18609
. : milestone, 18427,
tracing (18.559 ms) : 18375, 18743
. : milestone, 18559,
DacapoParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 11 metrics, 1 unstable metrics. Execution time for tomcatgantt
title tomcat - execution time [CI 0.99] : candidate=1.62.0-SNAPSHOT~9aac562f91, baseline=1.62.0-SNAPSHOT~081af53226
dateFormat X
axisFormat %s
section baseline
no_agent (1.484 ms) : 1473, 1496
. : milestone, 1484,
appsec (3.868 ms) : 3647, 4089
. : milestone, 3868,
iast (2.274 ms) : 2204, 2343
. : milestone, 2274,
iast_GLOBAL (2.306 ms) : 2237, 2376
. : milestone, 2306,
profiling (2.086 ms) : 2031, 2140
. : milestone, 2086,
tracing (2.083 ms) : 2029, 2137
. : milestone, 2083,
section candidate
no_agent (1.487 ms) : 1475, 1498
. : milestone, 1487,
appsec (3.815 ms) : 3593, 4037
. : milestone, 3815,
iast (2.272 ms) : 2203, 2342
. : milestone, 2272,
iast_GLOBAL (2.314 ms) : 2244, 2384
. : milestone, 2314,
profiling (2.091 ms) : 2036, 2145
. : milestone, 2091,
tracing (2.079 ms) : 2026, 2133
. : milestone, 2079,
Execution time for biojavagantt
title biojava - execution time [CI 0.99] : candidate=1.62.0-SNAPSHOT~9aac562f91, baseline=1.62.0-SNAPSHOT~081af53226
dateFormat X
axisFormat %s
section baseline
no_agent (15.534 s) : 15534000, 15534000
. : milestone, 15534000,
appsec (14.669 s) : 14669000, 14669000
. : milestone, 14669000,
iast (18.103 s) : 18103000, 18103000
. : milestone, 18103000,
iast_GLOBAL (17.927 s) : 17927000, 17927000
. : milestone, 17927000,
profiling (14.972 s) : 14972000, 14972000
. : milestone, 14972000,
tracing (15.087 s) : 15087000, 15087000
. : milestone, 15087000,
section candidate
no_agent (15.387 s) : 15387000, 15387000
. : milestone, 15387000,
appsec (14.781 s) : 14781000, 14781000
. : milestone, 14781000,
iast (17.991 s) : 17991000, 17991000
. : milestone, 17991000,
iast_GLOBAL (18.02 s) : 18020000, 18020000
. : milestone, 18020000,
profiling (14.966 s) : 14966000, 14966000
. : milestone, 14966000,
tracing (15.039 s) : 15039000, 15039000
. : milestone, 15039000,
|
Play instrumentation does not emit requestFilesFilenames; enabling the shared filename test would cause both suites to fail.
What Does This Do
Instruments multipart request handling in Akka HTTP, Grizzly (via Jersey), and Spring Boot to fire the
requestFilesFilenamesAppSec gateway event, enabling WAF rules that act on uploaded file names.Akka HTTP 10.0 / 10.6
Two distinct code paths handle multipart form data:
Unmarshal(...).to[Multipart.FormData.Strict]→handleMultipartStrictFormData: already instrumented in the parent commit; iteratesgetStrictParts()and callspart.getFilename().formFieldMultiMap/formFields→StrictFormCompanionInstrumentation→handleStrictFormData: previously missing. This path receivesMultipart$FormData$BodyPart$Strictobjects via reflection onStrictForm.Field; addedbodyPart.getFilename()extraction and firesrequestFilesFilenameswith full blocking support (AkkaBlockResponseFunction.setUnmarshallBlock(true)).Akka HTTP 10.6 is excluded from local builds (requires
akkaRepositoryToken); tested in CI only.Grizzly 2.x (Jersey 2.0 / 3.0)
Grizzly routes multipart requests through Jersey's
MultiPartReaderServerSide.readMultiPart().MultiPartReaderServerSideInstrumentationalready intercepted that method and firedrequestBodyProcessed, but never extracted filenames. AddedFormDataBodyPart.getContentDisposition().getFileName()extraction for each body part; firesrequestFilesFilenamesafterrequestBodyProcessedwith blocking support.Both
jersey-appsec-2.0(javax.ws.rs) andjersey-appsec-3.0(jakarta.ws.rs) are updated with identical logic.Spring Boot
Spring Boot over Tomcat routes multipart through
ParsePartsInstrumentation, which was already instrumented for filenames in a prior commit. Only thetestBodyFilenames()test flag was needed.akka-http-10.0(Unmarshal path)akka-http-10.0(formFieldMultiMap path)handleStrictFormDatanow firesrequestFilesFilenamesakka-http-10.6jersey-appsec-2.0jersey-appsec-3.0spring-webmvc-3.1testBodyFilenames() { true }grizzly-http-2.3.20testBodyFilenames() { true }Motivation
Part of APPSEC-61873 —
server.request.body.filenamesimplementation across server frameworks.Additional Notes
Depends on the Akka HTTP parent commit already merged on this branch.
Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labelsclose,fix, or any linking keywords when referencing an issueUse
solvesinstead, and assign the PR milestone to the issue