mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Added MULTIPART_UNMATCHED_BOUNDARY. Not very reliable, as it detects anything that looks like a boundary, which means any line that begins with -- but we don't think it's a boundary.
This commit is contained in:
parent
70324713e4
commit
c85773b343
@ -624,7 +624,7 @@ int multipart_process_chunk(modsec_rec *msr, const char *buf,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* here we loop through the data available, byte by byte */
|
/* here we loop through the available data, one byte at a time */
|
||||||
while(inleft > 0) {
|
while(inleft > 0) {
|
||||||
char c = *inptr;
|
char c = *inptr;
|
||||||
int process_buffer = 0;
|
int process_buffer = 0;
|
||||||
@ -645,71 +645,79 @@ int multipart_process_chunk(modsec_rec *msr, const char *buf,
|
|||||||
* or the end of our internal buffer
|
* or the end of our internal buffer
|
||||||
*/
|
*/
|
||||||
if ((c == 0x0a)||(msr->mpd->bufleft == 0)||(process_buffer)) {
|
if ((c == 0x0a)||(msr->mpd->bufleft == 0)||(process_buffer)) {
|
||||||
|
int processed_as_boundary = 0;
|
||||||
|
|
||||||
*(msr->mpd->bufptr) = 0;
|
*(msr->mpd->bufptr) = 0;
|
||||||
|
|
||||||
/* boundary preconditions: length of the line greater than
|
/* Do we have something that looks like a boundary? */
|
||||||
* the length of the boundary + the first two characters
|
if (msr->mpd->buf_contains_line
|
||||||
* are dashes "-"
|
&& (strlen(msr->mpd->buf) > 3)
|
||||||
*/
|
&& (((*(msr->mpd->buf) == '-'))&&(*(msr->mpd->buf + 1) == '-')) )
|
||||||
if ( msr->mpd->buf_contains_line
|
|
||||||
&& (strlen(msr->mpd->buf) > strlen(msr->mpd->boundary) + 2)
|
|
||||||
&& (((*(msr->mpd->buf) == '-'))&&(*(msr->mpd->buf + 1) == '-'))
|
|
||||||
&& (strncmp(msr->mpd->buf + 2, msr->mpd->boundary, strlen(msr->mpd->boundary)) == 0) )
|
|
||||||
{
|
{
|
||||||
char *boundary_end = msr->mpd->buf + 2 + strlen(msr->mpd->boundary);
|
/* Does it match our boundary? */
|
||||||
int is_final = 0;
|
if ((strlen(msr->mpd->buf) >= strlen(msr->mpd->boundary) + 2)
|
||||||
|
&& (strncmp(msr->mpd->buf + 2, msr->mpd->boundary, strlen(msr->mpd->boundary)) == 0) )
|
||||||
/* Is this the final boundary? */
|
|
||||||
if ((*boundary_end == '-')&&(*(boundary_end + 1)== '-')) {
|
|
||||||
is_final = 1;
|
|
||||||
boundary_end += 2;
|
|
||||||
|
|
||||||
if (msr->mpd->is_complete != 0) {
|
|
||||||
*error_msg = apr_psprintf(msr->mp,
|
|
||||||
"Multipart: Invalid boundary (final duplicate).");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allow for CRLF and LF line endings. */
|
|
||||||
if ( ( (*boundary_end == '\r')
|
|
||||||
&& (*(boundary_end + 1) == '\n')
|
|
||||||
&& (*(boundary_end + 2) == '\0') )
|
|
||||||
|| ( (*boundary_end == '\n')
|
|
||||||
&& (*(boundary_end + 1) == '\0') ) )
|
|
||||||
{
|
{
|
||||||
if (*boundary_end == '\n') {
|
char *boundary_end = msr->mpd->buf + 2 + strlen(msr->mpd->boundary);
|
||||||
msr->mpd->flag_lf_line = 1;
|
int is_final = 0;
|
||||||
|
|
||||||
|
/* Is this the final boundary? */
|
||||||
|
if ((*boundary_end == '-')&&(*(boundary_end + 1)== '-')) {
|
||||||
|
is_final = 1;
|
||||||
|
boundary_end += 2;
|
||||||
|
|
||||||
|
if (msr->mpd->is_complete != 0) {
|
||||||
|
*error_msg = apr_psprintf(msr->mp,
|
||||||
|
"Multipart: Invalid boundary (final duplicate).");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (multipart_process_boundary(msr, (is_final ? 1 : 0), error_msg) < 0) {
|
/* Allow for CRLF and LF line endings. */
|
||||||
|
if ( ( (*boundary_end == '\r')
|
||||||
|
&& (*(boundary_end + 1) == '\n')
|
||||||
|
&& (*(boundary_end + 2) == '\0') )
|
||||||
|
|| ( (*boundary_end == '\n')
|
||||||
|
&& (*(boundary_end + 1) == '\0') ) )
|
||||||
|
{
|
||||||
|
if (*boundary_end == '\n') {
|
||||||
|
msr->mpd->flag_lf_line = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multipart_process_boundary(msr, (is_final ? 1 : 0), error_msg) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_final) {
|
||||||
|
msr->mpd->is_complete = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
processed_as_boundary = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* error */
|
||||||
|
*error_msg = apr_psprintf(msr->mp,
|
||||||
|
"Multipart: Invalid boundary: %s",
|
||||||
|
log_escape_nq(msr->mp, msr->mpd->buf));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( (msr->mpd->flag_boundary_quoted)
|
||||||
|
&& (strlen(msr->mpd->buf) > strlen(msr->mpd->boundary) + 3)
|
||||||
|
&& (((*(msr->mpd->buf) == '-'))&&(*(msr->mpd->buf + 1) == '-'))
|
||||||
|
&& (*(msr->mpd->buf + 2) == '"')
|
||||||
|
&& (strncmp(msr->mpd->buf + 3, msr->mpd->boundary, strlen(msr->mpd->boundary)) == 0)
|
||||||
|
) {
|
||||||
|
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid boundary (quotes).");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_final) {
|
msr->mpd->flag_unmatched_boundary = 1;
|
||||||
msr->mpd->is_complete = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* error */
|
|
||||||
*error_msg = apr_psprintf(msr->mp,
|
|
||||||
"Multipart: Invalid boundary: %s",
|
|
||||||
log_escape_nq(msr->mp, msr->mpd->buf));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if ( msr->mpd->buf_contains_line
|
|
||||||
&& (msr->mpd->flag_boundary_quoted)
|
|
||||||
&& (strlen(msr->mpd->buf) > strlen(msr->mpd->boundary) + 3)
|
|
||||||
&& (((*(msr->mpd->buf) == '-'))&&(*(msr->mpd->buf + 1) == '-'))
|
|
||||||
&& (*(msr->mpd->buf + 2) == '"')
|
|
||||||
&& (strncmp(msr->mpd->buf + 3, msr->mpd->boundary, strlen(msr->mpd->boundary)) == 0)
|
|
||||||
) {
|
|
||||||
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid boundary (quotes).");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Process as data if it was not a boundary. */
|
||||||
|
if (processed_as_boundary == 0) {
|
||||||
if (msr->mpd->mpp == NULL) {
|
if (msr->mpd->mpp == NULL) {
|
||||||
msr->mpd->flag_data_before = 1;
|
msr->mpd->flag_data_before = 1;
|
||||||
msr_log(msr, 4, "Multipart: Ignoring data before first boundary.");
|
msr_log(msr, 4, "Multipart: Ignoring data before first boundary.");
|
||||||
|
@ -103,6 +103,7 @@ struct multipart_data {
|
|||||||
int flag_header_folding;
|
int flag_header_folding;
|
||||||
int flag_boundary_quoted;
|
int flag_boundary_quoted;
|
||||||
int flag_lf_line;
|
int flag_lf_line;
|
||||||
|
int flag_unmatched_boundary;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1308,6 +1308,18 @@ static int var_multipart_strict_error_generate(modsec_rec *msr, msre_var *var, m
|
|||||||
return var_simple_generate(var, vartab, mptmp, "0");
|
return var_simple_generate(var, vartab, mptmp, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* MULTIPART_UNMATCHED_BOUNDARY */
|
||||||
|
|
||||||
|
static int var_multipart_unmatched_boundary_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||||
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||||
|
{
|
||||||
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_unmatched_boundary != 0)) {
|
||||||
|
return var_simple_generate(var, vartab, mptmp, "1");
|
||||||
|
} else {
|
||||||
|
return var_simple_generate(var, vartab, mptmp, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* TIME */
|
/* TIME */
|
||||||
|
|
||||||
static int var_time_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
static int var_time_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||||
@ -2306,6 +2318,17 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
|||||||
PHASE_REQUEST_BODY
|
PHASE_REQUEST_BODY
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* MULTIPART_UNMATCHED_BOUNDARY */
|
||||||
|
msre_engine_variable_register(engine,
|
||||||
|
"MULTIPART_UNMATCHED_BOUNDARY",
|
||||||
|
VAR_SIMPLE,
|
||||||
|
0, 0,
|
||||||
|
NULL,
|
||||||
|
var_multipart_unmatched_boundary_generate,
|
||||||
|
VAR_CACHE,
|
||||||
|
PHASE_REQUEST_BODY
|
||||||
|
);
|
||||||
|
|
||||||
/* PATH_INFO */
|
/* PATH_INFO */
|
||||||
msre_engine_variable_register(engine,
|
msre_engine_variable_register(engine,
|
||||||
"PATH_INFO",
|
"PATH_INFO",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user