1 ### Multipart parser tests
3 # Final CRLF or not, we should still work
6 comment => "multipart parser (final CRLF)",
9 SecDebugLog $ENV{DEBUG_LOG}
11 SecRequestBodyAccess On
12 SecRule MULTIPART_STRICT_ERROR "\@eq 1" "phase:2,deny"
13 SecRule MULTIPART_UNMATCHED_BOUNDARY "\@eq 1" "phase:2,deny"
14 SecRule REQBODY_PROCESSOR_ERROR "\@eq 1" "phase:2,deny"
17 debug => [ qr/Adding request argument \(BODY\): name "a", value "1".*Adding request argument \(BODY\): name "b", value "2"/s, 1 ],
18 -debug => [ qr/Multipart error:/, 1 ],
24 request => new HTTP::Request(
25 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
27 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
29 normalize_raw_request_data(
31 -----------------------------69343412719991675451336310646
32 Content-Disposition: form-data; name="a"
35 -----------------------------69343412719991675451336310646
36 Content-Disposition: form-data; name="b"
39 -----------------------------69343412719991675451336310646--
46 comment => "multipart parser (no final CRLF)",
49 SecDebugLog $ENV{DEBUG_LOG}
51 SecRequestBodyAccess On
52 SecRule MULTIPART_STRICT_ERROR "\@eq 1" "phase:2,deny"
53 SecRule MULTIPART_UNMATCHED_BOUNDARY "\@eq 1" "phase:2,deny"
54 SecRule REQBODY_PROCESSOR_ERROR "\@eq 1" "phase:2,deny"
57 debug => [ qr/Adding request argument \(BODY\): name "a", value "1".*Adding request argument \(BODY\): name "b", value "2"/s, 1 ],
58 -debug => [ qr/Multipart error:/, 1 ],
64 request => new HTTP::Request(
65 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
67 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
69 normalize_raw_request_data(
71 -----------------------------69343412719991675451336310646
72 Content-Disposition: form-data; name="a"
75 -----------------------------69343412719991675451336310646
76 Content-Disposition: form-data; name="b"
79 -----------------------------69343412719991675451336310646--),
84 # Should work with a boundary of "boundary"
87 comment => "multipart parser (boundary contains \"boundary\")",
90 SecDebugLog $ENV{DEBUG_LOG}
92 SecRequestBodyAccess On
93 SecRule MULTIPART_STRICT_ERROR "\@eq 1" "phase:2,deny"
94 SecRule MULTIPART_UNMATCHED_BOUNDARY "\@eq 1" "phase:2,deny"
95 SecRule REQBODY_PROCESSOR_ERROR "\@eq 1" "phase:2,deny"
98 debug => [ qr/Adding request argument \(BODY\): name "a", value "1".*Adding request argument \(BODY\): name "b", value "2"/s, 1 ],
99 -debug => [ qr/Multipart error:/, 1 ],
105 request => new HTTP::Request(
106 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
108 "Content-Type" => "multipart/form-data; boundary=------------------------------------------------boundary",
110 normalize_raw_request_data(
112 --------------------------------------------------boundary
113 Content-Disposition: form-data; name="a"
116 --------------------------------------------------boundary
117 Content-Disposition: form-data; name="b"
120 --------------------------------------------------boundary--
127 comment => "multipart parser (boundary contains \"bOuNdArY\")",
133 SecDebugLog $ENV{DEBUG_LOG}
135 SecRequestBodyAccess On
136 SecRule MULTIPART_STRICT_ERROR "\@eq 1" "phase:2,deny"
137 SecRule MULTIPART_UNMATCHED_BOUNDARY "\@eq 1" "phase:2,deny"
138 SecRule REQBODY_PROCESSOR_ERROR "\@eq 1" "phase:2,deny"
141 debug => [ qr/Adding request argument \(BODY\): name "a", value "1".*Adding request argument \(BODY\): name "b", value "2"/s, 1 ],
142 -debug => [ qr/Multipart error:/, 1 ],
148 request => new HTTP::Request(
149 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
151 "Content-Type" => "multipart/form-data; boundary=--------0xKhTmLbOuNdArY",
153 normalize_raw_request_data(
155 ----------0xKhTmLbOuNdArY
156 Content-Disposition: form-data; name="a"
159 ----------0xKhTmLbOuNdArY
160 Content-Disposition: form-data; name="b"
163 ----------0xKhTmLbOuNdArY--
169 # We should handle data starting with a "--"
172 comment => "multipart parser (data contains \"--\")",
175 SecDebugLog $ENV{DEBUG_LOG}
177 SecRequestBodyAccess On
178 SecRule MULTIPART_STRICT_ERROR "\@eq 1" "phase:2,deny"
179 SecRule REQBODY_PROCESSOR_ERROR "\@eq 1" "phase:2,deny"
182 debug => [ qr/Adding request argument \(BODY\): name "a", value "--test".*Adding request argument \(BODY\): name "b", value "--"/s, 1 ],
183 -debug => [ qr/Multipart error:/, 1 ],
189 request => new HTTP::Request(
190 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
192 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
194 normalize_raw_request_data(
196 -----------------------------69343412719991675451336310646
197 Content-Disposition: form-data; name="a"
200 -----------------------------69343412719991675451336310646
201 Content-Disposition: form-data; name="b"
204 -----------------------------69343412719991675451336310646--),
209 # We should emit warnings for parsing errors
212 comment => "multipart parser error (no final boundary)",
215 SecDebugLog $ENV{DEBUG_LOG}
217 SecRequestBodyAccess On
218 SecAuditLog "$ENV{AUDIT_LOG}"
219 SecAuditEngine RelevantOnly
222 audit => [ qr/Final boundary missing/, 1 ],
223 debug => [ qr/Final boundary missing/, 1 ],
229 request => new HTTP::Request(
230 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
232 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
234 normalize_raw_request_data(
236 -----------------------------69343412719991675451336310646
237 Content-Disposition: form-data; name="a"
240 -----------------------------69343412719991675451336310646
241 Content-Disposition: form-data; name="b"
250 comment => "multipart parser error (no disposition)",
253 SecDebugLog $ENV{DEBUG_LOG}
255 SecRequestBodyAccess On
256 SecAuditLog "$ENV{AUDIT_LOG}"
257 SecAuditEngine RelevantOnly
260 -debug => [ qr/Multipart error:/, 1 ],
261 audit => [ qr/Part missing Content-Disposition header/, 1 ],
262 debug => [ qr/Part missing Content-Disposition header/, 1 ],
268 request => new HTTP::Request(
269 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
271 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
273 normalize_raw_request_data(
275 -----------------------------69343412719991675451336310646
278 -----------------------------69343412719991675451336310646
281 -----------------------------69343412719991675451336310646--
288 comment => "multipart parser error (bad disposition)",
291 SecDebugLog $ENV{DEBUG_LOG}
293 SecRequestBodyAccess On
294 SecAuditLog "$ENV{AUDIT_LOG}"
295 SecAuditEngine RelevantOnly
298 audit => [ qr/Invalid Content-Disposition header/, 1 ],
299 debug => [ qr/Invalid Content-Disposition header/, 1 ],
305 request => new HTTP::Request(
306 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
308 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
310 normalize_raw_request_data(
312 -----------------------------69343412719991675451336310646
313 Content-Disposition: form-data name="a"
316 -----------------------------69343412719991675451336310646
317 Content-Disposition: form-data name="b"
320 -----------------------------69343412719991675451336310646--
327 comment => "multipart parser error (no disposition name)",
330 SecDebugLog $ENV{DEBUG_LOG}
332 SecRequestBodyAccess On
333 SecAuditLog "$ENV{AUDIT_LOG}"
334 SecAuditEngine RelevantOnly
337 -debug => [ qr/Multipart error:/, 1 ],
338 audit => [ qr/Content-Disposition header missing name field/, 1 ],
339 debug => [ qr/Content-Disposition header missing name field/, 1 ],
345 request => new HTTP::Request(
346 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
348 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
350 normalize_raw_request_data(
352 -----------------------------69343412719991675451336310646
353 Content-Disposition: form-data;
356 -----------------------------69343412719991675451336310646
357 Content-Disposition: form-data;
360 -----------------------------69343412719991675451336310646--
365 # Zero length part name should not crash
368 comment => "multipart parser (zero length part name)",
371 SecDebugLog $ENV{DEBUG_LOG}
373 SecRequestBodyAccess On
374 #SecRule MULTIPART_STRICT_ERROR "\@eq 1" "phase:2,deny,status:403"
375 SecRule MULTIPART_UNMATCHED_BOUNDARY "\@eq 1" "phase:2,deny,status:403"
376 SecRule REQBODY_PROCESSOR_ERROR "\@eq 1" "phase:2,deny,status:403"
379 debug => [ qr/name: a.*variable: 1.*Invalid part header \(header name missing\)/s, 1 ],
380 -debug => [ qr/Adding request argument \(BODY\): name "b"/s, 1 ],
385 request => new HTTP::Request(
386 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
388 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
390 normalize_raw_request_data(
392 -----------------------------69343412719991675451336310646
393 Content-Disposition: form-data; name="a"
396 -----------------------------69343412719991675451336310646
398 -----------------------------69343412719991675451336310646
399 Content-Disposition: form-data; name="b"
402 -----------------------------69343412719991675451336310646--
407 # Data following final boundary should set flag
410 comment => "multipart parser (data after final boundary)",
413 SecDebugLog $ENV{DEBUG_LOG}
415 SecRequestBodyAccess On
416 SecRule MULTIPART_DATA_AFTER "\@eq 1" "phase:2,deny,status:403"
419 debug => [ qr/name: a.*variable: 1.*Ignoring data after last boundary/s, 1 ],
420 -debug => [ qr/Adding request argument \(BODY\): name "b"/s, 1 ],
425 request => new HTTP::Request(
426 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
428 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
430 normalize_raw_request_data(
432 -----------------------------69343412719991675451336310646
433 Content-Disposition: form-data; name="a"
436 -----------------------------69343412719991675451336310646--
437 -----------------------------69343412719991675451336310646
438 Content-Disposition: form-data; name="b"
441 -----------------------------69343412719991675451336310646--
446 # Single quoted data is invalid
449 comment => "multipart parser (C-D uses single quotes)",
452 SecDebugLog $ENV{DEBUG_LOG}
454 SecRequestBodyAccess On
455 #SecRule MULTIPART_STRICT_ERROR "\@eq 1" "phase:2,deny,status:403"
456 SecRule MULTIPART_INVALID_QUOTING "\@eq 1" "chain,phase:2,deny,status:403"
457 SecRule REQBODY_PROCESSOR_ERROR "\@eq 1"
460 debug => [ qr/name: a.*variable: 1.*Duplicate Content-Disposition name/s, 1 ],
461 -debug => [ qr/Adding request argument \(BODY\): name "b/s, 1 ],
466 request => new HTTP::Request(
467 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
469 "Content-Type" => "multipart/form-data; boundary=---------------------------69343412719991675451336310646",
471 normalize_raw_request_data(
473 -----------------------------69343412719991675451336310646
474 Content-Disposition: form-data; name="a"
477 -----------------------------69343412719991675451336310646
478 Content-Disposition: form-data; name=';filename="dummy';name=b;"
481 -----------------------------69343412719991675451336310646--