Commit c3d2ee3
authored
Add server.request.body.filenames AppSec address for Undertow and Play (#11174)
Add server.request.body.filenames support for Undertow and Play
- 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.
Fix server.request.body.filenames for in-memory uploads in Undertow 2.2
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.
Decouple requestBodyProcessed and requestFilesFilenames callbacks in 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.
Fix Scala 2.13 muzzle incompatibility in Play multipart filenames support
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.
Skip filenames WAF callback when body callback already caused a block
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.
Add unit tests for FormDataMap and BodyParserHelpers.jsValueToJavaObject
Fix tryCommitBlockingResponse return-value check; simplify appsec guard; add play-2.5 unit tests
Align play-appsec-2.6 handleMultipartFilenames with play-appsec-2.5 safe pattern
Cache MultipartFormData.files() Method to avoid per-request reflection lookup
Fix FormDataMapTest anonymous FormValue missing undertow 2.2.x methods
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.
Use Proxy in FormDataMapTest to handle undertow 2.0/2.2 interface differences
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.
Move testBodyFilenames from AbstractPlayServerTest to play-appsec-2.6 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.
Fix dual-fire rule and BlockingException propagation clarity in Play and Undertow multipart
- Play 2.5/2.6 handleMultipartFormData: apply pendingBlock pattern so both body
and filenames callbacks always fire even when one of them blocks first
- Play 2.5/2.6: split catch(Exception) into explicit catch(BlockingException)/catch(Exception)
to make blocking propagation unambiguous (was relying on non-obvious re-throw in handleException)
- Play 2.5/2.6: extract collectFilenames() as package-private to enable unit testing
- Play 2.5/2.6 BodyParserHelpersTest: add collectFilenames unit tests with real FilePart instances
- Undertow MultiPartUploadHandlerInstrumentation: remove && t == null guard on filenames
callback so filenames fires even when body already blocked
Make filenames blocking guard consistent with body blocking guard in Undertow advice
Both now use `if (success && t == null)` to avoid overwriting a pre-existing
throwable, matching the pattern already used in the body-callback block.
Fix collectFilenames to accept java.util.Iterator to enable unit testing
Adapt the scala.collection.Iterator from MULTIPART_FILES_METHOD with an
anonymous java.util.Iterator wrapper at the call site, so collectFilenames
can be called directly from Java tests without a Scala iterator.
Replace anonymous iterator with named ScalaIteratorAdapter; add to helperClassNames
The anonymous java.util.Iterator class compiled as BodyParserHelpers$1 was
missing from helperClassNames, causing muzzle validation failures. Replace
with a named static inner class ScalaIteratorAdapter and declare it explicitly
in all helperClassNames arrays that already reference BodyParserHelpers.
Guard filenames tryCommitBlockingResponse if body already blocked in Undertow
UndertowBlockResponseFunction.tryCommitBlockingResponse is not idempotent:
it overwrites exchange attachments and re-dispatches on the IO thread on every
call. Move the t == null guard before the call so the filename blocking path
is skipped when the body blocking path has already committed a response.
Trigger devflow re-evaluation
Merge branch 'master' into alejandro.gonzalez/APPSEC-61873-4-undertow-play
Co-authored-by: alejandro.gonzalez <alejandro.gonzalez@datadoghq.com>1 parent 43fc0e8 commit c3d2ee3
24 files changed
Lines changed: 779 additions & 35 deletions
File tree
- dd-java-agent/instrumentation
- play
- play-appsec-2.5/src
- main/java/datadog/trace/instrumentation/play25/appsec
- test
- groovy/datadog/trace/instrumentation/play25/server
- java/datadog/trace/instrumentation/play25/appsec
- play-appsec-2.6/src
- main/java/datadog/trace/instrumentation/play26/appsec
- test
- groovy/datadog/trace/instrumentation/play26/server
- java/datadog/trace/instrumentation/play26/appsec
- undertow
- undertow-2.0/src
- main/java/datadog/trace/instrumentation/undertow
- test
- groovy
- java/datadog/trace/instrumentation/undertow
- undertow-2.2/src/test/groovy
Lines changed: 111 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| |||
47 | 48 | | |
48 | 49 | | |
49 | 50 | | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
50 | 66 | | |
51 | 67 | | |
52 | 68 | | |
| |||
105 | 121 | | |
106 | 122 | | |
107 | 123 | | |
108 | | - | |
109 | | - | |
110 | | - | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
111 | 135 | | |
112 | 136 | | |
113 | 137 | | |
114 | | - | |
115 | | - | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
116 | 147 | | |
117 | | - | |
| 148 | + | |
118 | 149 | | |
| 150 | + | |
| 151 | + | |
119 | 152 | | |
120 | 153 | | |
121 | 154 | | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
122 | 209 | | |
123 | 210 | | |
124 | 211 | | |
| |||
302 | 389 | | |
303 | 390 | | |
304 | 391 | | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
305 | 410 | | |
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| |||
Lines changed: 5 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
86 | 91 | | |
87 | 92 | | |
88 | 93 | | |
| |||
Lines changed: 167 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
0 commit comments