Skip to content

Commit 371e687

Browse files
committed
Implement request body partial processing for SecRequestBodyNoFilesLimit
1 parent 8ccfc6a commit 371e687

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

apache2/apache2_io.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,22 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
301301

302302
if (msr->reqbody_length + buflen > (apr_size_t)msr->txcfg->reqbody_limit && msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL) {
303303
buflen = (apr_size_t)msr->txcfg->reqbody_limit - msr->reqbody_length;
304+
if (msr->txcfg->debuglog_level >= 9) {
305+
msr_log(msr, 9, "Input filter: Bucket type %s shortened by %" APR_SIZE_T_FMT " bytes because of reqbody_limit and ProcessPartial.",
306+
bucket->type->name, (apr_size_t)msr->txcfg->reqbody_limit - msr->reqbody_length);
307+
}
308+
304309
finished_reading = 1;
305310
modsecurity_request_body_enable_partial_processing(msr);
311+
} else if ( (msr->msc_reqbody_no_files_length > (unsigned long)msr->txcfg->reqbody_no_files_limit)
312+
&& (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL))
313+
{
314+
if (msr->txcfg->debuglog_level >= 9) {
315+
msr_log(msr, 9, "Input filter: Bucket type %s skip storing because of no_files_limit and ProcessPartial.",
316+
bucket->type->name);
317+
}
318+
buflen = 0;
319+
finished_reading = 1;
306320
}
307321

308322
msr->reqbody_length += buflen;

apache2/msc_multipart.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,18 @@ static int multipart_process_part_header(modsec_rec *msr, char **error_msg) {
273273
/* The buffer is data so increase the data length counter. */
274274
msr->msc_reqbody_no_files_length += (MULTIPART_BUF_SIZE - msr->mpd->bufleft);
275275

276+
/* Enable partial processing if the no_files_length exceeds the limit and the limit action is ProcessPartial. */
277+
if ((msr->msc_reqbody_no_files_length > (unsigned long)msr->txcfg->reqbody_no_files_limit)
278+
&& (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL))
279+
{
280+
msr->mpd->bufleft -= msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit;
281+
if (msr->txcfg->debuglog_level >= 9) {
282+
msr_log(msr, 9, "MULTIPART: length shortend by %" APR_SIZE_T_FMT " bytes because of no_files_len limit.",
283+
msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit);
284+
}
285+
modsecurity_request_body_enable_partial_processing(msr);
286+
}
287+
276288
if (len > 1) {
277289
if (msr->mpd->buf[len - 2] == '\r') {
278290
msr->mpd->flag_crlf_line = 1;
@@ -587,6 +599,18 @@ static int multipart_process_part_data(modsec_rec *msr, char **error_msg) {
587599
/* The buffer contains data so increase the data length counter. */
588600
msr->msc_reqbody_no_files_length += (MULTIPART_BUF_SIZE - msr->mpd->bufleft) + msr->mpd->reserve[0];
589601

602+
/* Enable partial processing if the no_files_length exceeds the limit and the limit action is ProcessPartial. */
603+
if ((msr->msc_reqbody_no_files_length > (unsigned long)msr->txcfg->reqbody_no_files_limit)
604+
&& (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL))
605+
{
606+
msr->mpd->bufleft -= msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit;
607+
if (msr->txcfg->debuglog_level >= 9) {
608+
msr_log(msr, 9, "MULTIPART: length shortend by %" APR_SIZE_T_FMT " bytes because of no_files_len limit.",
609+
msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit);
610+
}
611+
modsecurity_request_body_enable_partial_processing(msr);
612+
}
613+
590614
/* add this part to the list of parts */
591615

592616
/* remember where we started */

apache2/msc_reqbody.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,18 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr,
362362
/* Increase per-request data length counter. */
363363
msr->msc_reqbody_no_files_length += length;
364364

365+
/* Enable partial processing if no_files_len exceeds limit and action is ProcessPartial */
366+
if ( (msr->msc_reqbody_no_files_length > (unsigned long)msr->txcfg->reqbody_no_files_limit)
367+
&& (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL))
368+
{
369+
length -= msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit;
370+
if (msr->txcfg->debuglog_level >= 9) {
371+
msr_log(msr, 9, "XML: length shortened by %" APR_SIZE_T_FMT " bytes because of no_files_len limit.",
372+
msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit);
373+
}
374+
modsecurity_request_body_enable_partial_processing(msr);
375+
}
376+
365377
/* Process data as XML. */
366378
if (xml_process_chunk(msr, data, length, &my_error_msg) < 0) {
367379
*error_msg = apr_psprintf(msr->mp, "XML parsing error: %s", my_error_msg);
@@ -374,6 +386,18 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr,
374386
/* Increase per-request data length counter. */
375387
msr->msc_reqbody_no_files_length += length;
376388

389+
/* Enable partial processing if no_files_len exceeds limit and action is ProcessPartial */
390+
if ( (msr->msc_reqbody_no_files_length > (unsigned long)msr->txcfg->reqbody_no_files_limit)
391+
&& (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL))
392+
{
393+
length -= msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit;
394+
if (msr->txcfg->debuglog_level >= 9) {
395+
msr_log(msr, 9, "JSON: length shortened by %" APR_SIZE_T_FMT " bytes because of no_files_len limit.",
396+
msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit);
397+
}
398+
modsecurity_request_body_enable_partial_processing(msr);
399+
}
400+
377401
/* Process data as JSON. */
378402
#ifdef WITH_YAJL
379403
if (json_process_chunk(msr, data, length, &my_error_msg) < 0) {
@@ -393,6 +417,18 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr,
393417
/* Increase per-request data length counter. */
394418
msr->msc_reqbody_no_files_length += length;
395419

420+
/* Enable partial processing if no_files_len exceeds limit and action is ProcessPartial */
421+
if ( (msr->msc_reqbody_no_files_length > (unsigned long)msr->txcfg->reqbody_no_files_limit)
422+
&& (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL))
423+
{
424+
length -= msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit;
425+
if (msr->txcfg->debuglog_level >= 9) {
426+
msr_log(msr, 9, "URLENCODED: length shortened by %" APR_SIZE_T_FMT " bytes because of no_files_len limit.",
427+
msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit);
428+
}
429+
modsecurity_request_body_enable_partial_processing(msr);
430+
}
431+
396432
/* Do nothing else, URLENCODED processor does not support streaming. */
397433
}
398434
else {
@@ -403,6 +439,18 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr,
403439
} else if (msr->txcfg->reqbody_buffering != REQUEST_BODY_FORCEBUF_OFF) {
404440
/* Increase per-request data length counter if forcing buffering. */
405441
msr->msc_reqbody_no_files_length += length;
442+
443+
/* Enable partial processing if no_files_len exceeds limit and action is ProcessPartial */
444+
if ( (msr->msc_reqbody_no_files_length > (unsigned long)msr->txcfg->reqbody_no_files_limit)
445+
&& (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL))
446+
{
447+
length -= msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit;
448+
if (msr->txcfg->debuglog_level >= 9) {
449+
msr_log(msr, 9, "forceBuf: length shortened by %" APR_SIZE_T_FMT " bytes because of no_files_len limit.",
450+
msr->msc_reqbody_no_files_length - (unsigned long)msr->txcfg->reqbody_no_files_limit);
451+
}
452+
modsecurity_request_body_enable_partial_processing(msr);
453+
}
406454
}
407455

408456
/* Check that we are not over the request body no files limit. */

0 commit comments

Comments
 (0)