1515#include "modsecurity.h"
1616#include <ctype.h>
1717#include <sys/stat.h>
18+ #include <stdint.h>
1819
1920#include "msc_multipart.h"
2021#include "msc_util.h"
@@ -94,7 +95,8 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
9495if (* p != ';' )return -2 ;
9596p ++ ;
9697
97- int filenamePresent = 0 ;
98+ uint8_t filename_present = FALSE;
99+ uint8_t filename_ext_present = FALSE;
98100
99101/* parse the appended parts */
100102while (* p != '\0' ) {
@@ -206,7 +208,17 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
206208
207209if (strcmp (name ,"filename*" )== 0 )
208210 {
209- // Make sure to turn of INVALID quoting since RFC 5987 expects quotes in the filename format.
211+ // We allow only one instance of `filename*` attribute to be present in the Content-Disposition header.
212+ if (filename_ext_present )
213+ {
214+ msr_log (msr ,4 ,"Multipart: Warning: Duplicate Content-Disposition filename*: %s" ,
215+ log_escape_nq (msr -> mp ,decoded_filename ));
216+ return -17 ;
217+ }
218+
219+ filename_ext_present = TRUE;
220+
221+ // Make sure to turn of INVALID quoting since RFC 5987 expects quotes in the filename format.
210222msr -> mpd -> flag_invalid_quoting = 0 ;
211223
212224decoded_filename = rfc5987_decode (msr -> mp ,value );
@@ -218,34 +230,27 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
218230 }
219231msr -> multipart_filename = decoded_filename ;
220232
221-
222- if (msr -> mpd -> mpp -> filenameext != NULL ) {
223- msr_log (msr ,4 ,"Multipart: Warning: Duplicate Content-Disposition filename*: %s" ,
224- log_escape_nq (msr -> mp ,decoded_filename ));
225- return -17 ;
226- }
227-
228- msr -> mpd -> mpp -> filenameext = apr_pstrdup (msr -> mp ,decoded_filename );
229-
230233// The `filename*` RCF 5987 encoded filename always overrides the `filename` parameter in content-disposition header.
231- msr -> mpd -> mpp -> filename = msr -> mpd -> mpp -> filenameext ;
234+ msr -> mpd -> mpp -> filename = apr_pstrdup ( msr -> mp , decoded_filename ) ;
232235
233236// Re-run the validation check on the filename. We shouldn't be seeing quotes in the UTF-8 formatted filename either.
234237validate_quotes (msr ,msr -> mpd -> mpp -> filename );
235238 }
236239else
237240 {
238- // Process the `filename` attribute in the content-disposition header only if `filename*` does not exist.
239- filenamePresent ++ ;
240- if (filenamePresent > 1 )
241+ // We allow only one instance of `filename` attribute to be present in the Content-Disposition header.
242+ if (filename_present )
241243 {
242244// Duplicate `filename` attributes are not allowed.
243245msr_log (msr ,4 ,"Multipart: Warning: Duplicate Content-Disposition filename: %s" ,
244246log_escape_nq (msr -> mp ,decoded_filename ));
245247return -15 ;
246248 }
247249
248- if (msr -> mpd -> mpp -> filenameext == NULL )
250+ filename_present = TRUE;
251+
252+ // Process the `filename` attribute in the content-disposition header only if `filename*` does not exist.
253+ if (!filename_ext_present )
249254 {
250255// "name == 'filename'"
251256decoded_filename = value ;