mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-18 07:06:13 +03:00
Handle "filename*" field in MP header
This commit is contained in:
parent
fd0e042abc
commit
cd4905b889
@ -20,6 +20,9 @@
|
|||||||
#include "msc_util.h"
|
#include "msc_util.h"
|
||||||
#include "msc_parsers.h"
|
#include "msc_parsers.h"
|
||||||
|
|
||||||
|
static const char* mime_charset_special = "!#$%&+-^_`{}~";
|
||||||
|
static const char* attr_char_special = "!#$&+-.^_`~";
|
||||||
|
|
||||||
void validate_quotes(modsec_rec *msr, char *data, char quote) {
|
void validate_quotes(modsec_rec *msr, char *data, char quote) {
|
||||||
assert(msr != NULL);
|
assert(msr != NULL);
|
||||||
int i, len;
|
int i, len;
|
||||||
@ -85,6 +88,7 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
|
|||||||
assert(msr != NULL);
|
assert(msr != NULL);
|
||||||
assert(c_d_value != NULL);
|
assert(c_d_value != NULL);
|
||||||
char *p = NULL, *t = NULL;
|
char *p = NULL, *t = NULL;
|
||||||
|
char *filenameStar = NULL;
|
||||||
|
|
||||||
/* accept only what we understand */
|
/* accept only what we understand */
|
||||||
if (strncmp(c_d_value, "form-data", 9) != 0) {
|
if (strncmp(c_d_value, "form-data", 9) != 0) {
|
||||||
@ -130,7 +134,41 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
char quote = '\0';
|
char quote = '\0';
|
||||||
if ((*p == '"') || (*p == '\'')) {
|
if (name == "filename*") {
|
||||||
|
/* filename*=charset'[optional-language]'filename */
|
||||||
|
/* Read beyond the charset and the optional language*/
|
||||||
|
const char* start_of_charset = p;
|
||||||
|
while ((*p != '\0') && (isalnum(*p) || (strchr(mime_charset_special, *p)))) {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if ((*p != '\'') || (p == start_of_charset)) {
|
||||||
|
return -16; // Must be at least one legit char before ' for start of language
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
while ((*p != '\0') && (*p != '\'')) {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (*p != '\'') {
|
||||||
|
return -17; // Single quote for end-of-language not found
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* Now read what should be the actual filename */
|
||||||
|
const char* start_of_filename = p;
|
||||||
|
while ((*p != '\0') && (*p != ';')) {
|
||||||
|
if (*p == '%') {
|
||||||
|
if ((*(p+1) == '\0') || (!isxdigit(*(p+1))) || (!isxdigit(*(p+2)))) {
|
||||||
|
return -18;
|
||||||
|
}
|
||||||
|
p += 3;
|
||||||
|
} else if (isalnum(*p) || strchr(attr_char_special, *p)) {
|
||||||
|
p++;
|
||||||
|
} else {
|
||||||
|
return -19;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value = apr_pmemdup(msr->mp, start_of_filename, p - start_of_filename);
|
||||||
|
} else if ((*p == '"') || (*p == '\'')) {
|
||||||
/* quoted */
|
/* quoted */
|
||||||
quote = *p; // remember which quote character was used for the value
|
quote = *p; // remember which quote character was used for the value
|
||||||
|
|
||||||
@ -205,8 +243,7 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
|
|||||||
log_escape_nq(msr->mp, value));
|
log_escape_nq(msr->mp, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (strcmp(name, "filename") == 0) {
|
||||||
if (strcmp(name, "filename") == 0) {
|
|
||||||
|
|
||||||
validate_quotes(msr, value, quote);
|
validate_quotes(msr, value, quote);
|
||||||
|
|
||||||
@ -223,6 +260,17 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
|
|||||||
msr_log(msr, 9, "Multipart: Content-Disposition filename: %s",
|
msr_log(msr, 9, "Multipart: Content-Disposition filename: %s",
|
||||||
log_escape_nq(msr->mp, value));
|
log_escape_nq(msr->mp, value));
|
||||||
}
|
}
|
||||||
|
} else if (strcmp(name, "filename*") == 0) {
|
||||||
|
if (filenameStar != NULL && strlen(filenameStar) != 0) {
|
||||||
|
msr_log(msr, 4,
|
||||||
|
"Multipart: Warning: Duplicate Content-Disposition filename*: %s.", log_escape_nq(msr->mp, value));
|
||||||
|
return -20;
|
||||||
|
}
|
||||||
|
filenameStar = apr_pstrdup(msr->mp, value);
|
||||||
|
if (msr->txcfg->debuglog_level >= 9) {
|
||||||
|
msr_log(msr, 9, "Multipart: Content-Disposition filename*: %s.",
|
||||||
|
log_escape_nq(msr->mp, value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else return -11;
|
else return -11;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user