diff --git a/src/request_body_processor/multipart.cc b/src/request_body_processor/multipart.cc index 3ae591671e..0b35672bc9 100644 --- a/src/request_body_processor/multipart.cc +++ b/src/request_body_processor/multipart.cc @@ -362,11 +362,11 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) { const char* start_of_filename = p; while ((*p != '\0') && (*p != ';')) { if (*p == '%') { - if ((*(p+1) == '\0') || (!isxdigit(*(p+1))) || (!isxdigit(*(p+2)))) { + if ((*(p+1) == '\0') || (!isxdigit(*(p+1))) || (*(p+2) == '\0') || (!isxdigit(static_cast(*(p+2))))) { return -18; } p += 3; - } else if (isalnum(*p) || strchr(attr_char_special, *p)) { + } else if (isalnum(static_cast(*p)) || strchr(attr_char_special, *p)) { p++; } else { return -19; @@ -415,7 +415,12 @@ int Multipart::parse_content_disposition(const char *c_d_value, int offset) { value.append((p++), 1); } - p++; /* go over the quote at the end */ + if (*p == quote) { + p++; /* go over the quote at the end */ + } else { + m_flag_invalid_quoting = 1; + return -15; /* closing quote not found */ + } } else { /* not quoted */ diff --git a/test/test-cases/regression/request-body-parser-multipart.json b/test/test-cases/regression/request-body-parser-multipart.json index 72cc3a1438..84e61c1e0d 100644 --- a/test/test-cases/regression/request-body-parser-multipart.json +++ b/test/test-cases/regression/request-body-parser-multipart.json @@ -3417,5 +3417,56 @@ "SecruleEngine On", "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "title": "multipart parser (invalid part header - missing trailing quote)", + "client": { + "ip": "200.249.12.31", + "port": 123 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "localhost", + "User-Agent": "curl/7.38.0", + "Accept": "*/*", + "Content-Length": "145", + "Content-Type": "multipart/form-data; boundary=a", + "Expect": "100-continue" + }, + "uri": "/", + "method": "POST", + "body": [ + "--a\r\n", + "Content-Disposition: form-data; name=\"file\"; filename=\"1.jsp\r\n", + "\r\n", + "Some content\r\n", + "--a--\r\n" + ] + }, + "response": { + "headers": { + "Date": "Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified": "Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type": "text/html", + "Content-Length": "8" + }, + "body": [ + "no need." + ] + }, + "expected": { + "debug_log": "Multipart: Invalid Content-Disposition header \\(-15\\): form-data; name=\"file\"; filename=\"1.jsp", + "http_code": 403 + }, + "rules": [ + "SecruleEngine On", + "SecRule REQBODY_PROCESSOR_ERROR \"@eq 1\" \"phase:2,deny,status:403,id:500077\"" + ] } ]