Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apache2/apache2.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
#if (!defined(NO_MODSEC_API))
/* Optional functions. */

typedef int (*fn_op_param_init_t)(msre_rule* rule, char** error_msg);

Check warning on line 30 in apache2/apache2.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

"using" should be preferred to "typedef" for type aliasing.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ0BleMSPdf_vvzVEcUB&open=AZ0BleMSPdf_vvzVEcUB&pullRequest=3516
typedef int (*fn_op_execute_t)(modsec_rec* msr, msre_rule* rule, msre_var* var, char** error_msg);

Check warning on line 31 in apache2/apache2.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

"using" should be preferred to "typedef" for type aliasing.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ0BleMSPdf_vvzVEcUC&open=AZ0BleMSPdf_vvzVEcUC&pullRequest=3516
APR_DECLARE_OPTIONAL_FN(void, modsec_register_tfn, (const char *name, void *fn));
APR_DECLARE_OPTIONAL_FN(void, modsec_register_operator, (const char *name, void *fn_init, void *fn_exec));
APR_DECLARE_OPTIONAL_FN(void, modsec_register_operator, (const char *name, fn_op_param_init_t fn_init, fn_op_execute_t fn_exec));
APR_DECLARE_OPTIONAL_FN(void, modsec_register_variable,
(const char *name, unsigned int type,
unsigned int argc_min, unsigned int argc_max,
Expand Down
4 changes: 2 additions & 2 deletions apache2/mod_security2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1406,9 +1406,9 @@ static void modsec_register_tfn(const char *name, void *fn) {
* This function is exported for other Apache modules to
* register new operators.
*/
static void modsec_register_operator(const char *name, void *fn_init, void *fn_exec) {
static void modsec_register_operator(const char* name, fn_op_param_init_t fn_init, fn_op_execute_t fn_exec) {
if (modsecurity != NULL) {
msre_engine_op_register(modsecurity->msre, name, (fn_op_param_init_t)fn_init, (fn_op_execute_t)fn_exec);
msre_engine_op_register(modsecurity->msre, name, fn_init, fn_exec);
}
}

Expand Down
63 changes: 56 additions & 7 deletions apache2/msc_multipart.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "msc_util.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) {
assert(msr != NULL);
int i, len;
Expand Down Expand Up @@ -81,11 +84,12 @@
/**
*
*/
static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value) {

Check failure on line 87 in apache2/msc_multipart.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 147 to the 25 allowed.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ0BleHNPdf_vvzVEcT2&open=AZ0BleHNPdf_vvzVEcT2&pullRequest=3516
assert(msr != NULL);
assert(c_d_value != NULL);
char *p = NULL, *t = NULL;

char* filenameStar = NULL;

/* accept only what we understand */
if (strncmp(c_d_value, "form-data", 9) != 0) {
return -1;
Expand Down Expand Up @@ -124,13 +128,46 @@
while((*p == '\t') || (*p == ' ')) p++;
if (*p == '\0') return -6;

/* Accept both quotes as some backends will accept them, but
* technically "'" is invalid and so flag_invalid_quoting is
* set so the user can deal with it in the rules if they so wish.
*/

char quote = '\0';
if ((*p == '"') || (*p == '\'')) {
if (strcmp(name, "filename*") == 0) {
/* 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 (isalnum(*p) || *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 == '%') {

Check failure on line 152 in apache2/msc_multipart.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ2VPyiSLkRFsv27ohkL&open=AZ2VPyiSLkRFsv27ohkL&pullRequest=3516
if ((!isxdigit(*(p + 1))) || (!isxdigit(*(p + 2)))) {
return -18;
}
p += 3;
}
else if ((*p != '\0') && (isalnum(*p) || strchr(mime_charset_special, *p))) {
p++;
}
else {
return -19;
}
}
value = apr_pmemdup(msr->mp, start_of_filename, p - start_of_filename);
} else if ((*p == '"') || (*p == '\'')) {
/* Accept both quotes as some backends will accept them, but
* technically "'" is invalid and so flag_invalid_quoting is
* set so the user can deal with it in the rules if they so wish.
*/
/* quoted */
quote = *p; // remember which quote character was used for the value

Expand All @@ -146,7 +183,7 @@
t = value;

while(*p != '\0') {
if (*p == '\\') {

Check failure on line 186 in apache2/msc_multipart.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ2VPyiSLkRFsv27ohkM&open=AZ2VPyiSLkRFsv27ohkM&pullRequest=3516
if (*(p + 1) == '\0') {
/* improper escaping */
return -8;
Expand Down Expand Up @@ -205,7 +242,7 @@
log_escape_nq(msr->mp, value));
}
}
else

Check failure on line 245 in apache2/msc_multipart.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use curly braces or indentation to denote the code conditionally executed by this statement.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ0BleHNPdf_vvzVEcT-&open=AZ0BleHNPdf_vvzVEcT-&pullRequest=3516
if (strcmp(name, "filename") == 0) {

validate_quotes(msr, value, quote);
Expand All @@ -223,6 +260,18 @@
msr_log(msr, 9, "Multipart: Content-Disposition filename: %s",
log_escape_nq(msr->mp, value));
}
else if (strcmp(name, "filename*") == 0) {
if (filenameStar != NULL) {

Check failure on line 264 in apache2/msc_multipart.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ0BleHNPdf_vvzVEcT8&open=AZ0BleHNPdf_vvzVEcT8&pullRequest=3516
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) {

Check failure on line 270 in apache2/msc_multipart.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ0BleHNPdf_vvzVEcT9&open=AZ0BleHNPdf_vvzVEcT9&pullRequest=3516
msr_log(msr, 9, "Multipart: Content-Disposition filename*: %s.",
log_escape_nq(msr->mp, value));
}
}
}
else return -11;

Expand Down