Skip to content

Commit 1c0e953

Browse files
author
Felipe Zimmerle
committed
Adds collection FILES_TMP_CONTENT
The collection is filled with a key-value set where value is the content of the file which was uploaded. This collection can be used with all supported operators, however, SecTmpSaveUploadedFiles should be set to 'On' in order to have this collection filled. Note that @inspectFile is now depending on SecTmpSaveUploadedFiles. This is necessary to keep performance while such functionalities where not used.
1 parent 87df482 commit 1c0e953

File tree

2 files changed

+134
-5
lines changed

2 files changed

+134
-5
lines changed

apache2/apache2_config.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -912,11 +912,6 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
912912
}
913913
}
914914

915-
/* Optimisation */
916-
if ((rule->op_name != NULL)&&(strcasecmp(rule->op_name, "inspectFile") == 0)) {
917-
dcfg->upload_validates_files = 1;
918-
}
919-
920915
/* Create skip table if one does not already exist. */
921916
if (dcfg->tmp_rule_placeholders == NULL) {
922917
dcfg->tmp_rule_placeholders = apr_table_make(cmd->pool, 10);
@@ -2449,6 +2444,30 @@ static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg,
24492444
return NULL;
24502445
}
24512446

2447+
static const char *cmd_upload_save_tmp_files(cmd_parms *cmd, void *_dcfg,
2448+
const char *p1)
2449+
{
2450+
directory_config *dcfg = (directory_config *)_dcfg;
2451+
2452+
if (dcfg == NULL) return NULL;
2453+
2454+
if (strcasecmp(p1, "on") == 0)
2455+
{
2456+
dcfg->upload_validates_files = 1;
2457+
}
2458+
else if (strcasecmp(p1, "off") == 0)
2459+
{
2460+
dcfg->upload_validates_files = 0;
2461+
}
2462+
else
2463+
{
2464+
return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for SecTmpSaveUploadedFiles: %s",
2465+
p1);
2466+
}
2467+
2468+
return NULL;
2469+
}
2470+
24522471
static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1)
24532472
{
24542473
directory_config *dcfg = (directory_config *)_dcfg;
@@ -3685,6 +3704,14 @@ const command_rec module_directives[] = {
36853704
"On or Off"
36863705
),
36873706

3707+
AP_INIT_TAKE1 (
3708+
"SecTmpSaveUploadedFiles",
3709+
cmd_upload_save_tmp_files,
3710+
NULL,
3711+
CMD_SCOPE_ANY,
3712+
"On or Off"
3713+
),
3714+
36883715
AP_INIT_TAKE1 (
36893716
"SecWebAppId",
36903717
cmd_web_app_id,

apache2/re_variables.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,97 @@ static int var_resource_generate(modsec_rec *msr, msre_var *var, msre_rule *rule
11131113
return count;
11141114
}
11151115

1116+
/* FILES_TMP_CONTENT */
1117+
1118+
static int var_files_tmp_contents_generate(modsec_rec *msr, msre_var *var,
1119+
msre_rule *rule, apr_table_t *vartab, apr_pool_t *mptmp)
1120+
{
1121+
multipart_part **parts = NULL;
1122+
int i, count = 0;
1123+
1124+
if (msr->mpd == NULL) return 0;
1125+
1126+
parts = (multipart_part **)msr->mpd->parts->elts;
1127+
for (i = 0; i < msr->mpd->parts->nelts; i++)
1128+
{
1129+
if ((parts[i]->type == MULTIPART_FILE) &&
1130+
(parts[i]->tmp_file_name != NULL))
1131+
{
1132+
int match = 0;
1133+
1134+
/* Figure out if we want to include this variable. */
1135+
if (var->param == NULL)
1136+
{
1137+
match = 1;
1138+
}
1139+
else
1140+
{
1141+
if (var->param_data != NULL)
1142+
{
1143+
/* Regex. */
1144+
char *my_error_msg = NULL;
1145+
if (!(msc_regexec((msc_regex_t *)var->param_data,
1146+
parts[i]->name, strlen(parts[i]->name),
1147+
&my_error_msg) == PCRE_ERROR_NOMATCH))
1148+
{
1149+
match = 1;
1150+
}
1151+
}
1152+
else
1153+
{
1154+
/* Simple comparison. */
1155+
if (strcasecmp(parts[i]->name, var->param) == 0)
1156+
{
1157+
match = 1;
1158+
}
1159+
}
1160+
}
1161+
/* If we had a match add this argument to the collection. */
1162+
if (match) {
1163+
static int buf_size = 1024;
1164+
char buf[buf_size];
1165+
FILE *file;
1166+
size_t nread;
1167+
char *full_content = NULL;
1168+
size_t total_lenght = 0;
1169+
1170+
file = fopen(parts[i]->tmp_file_name, "r");
1171+
if (file == NULL)
1172+
{
1173+
continue;
1174+
}
1175+
1176+
while ((nread = fread(buf, 1, buf_size-1, file)) > 0)
1177+
{
1178+
total_lenght += nread;
1179+
buf[nread] = '\0';
1180+
if (full_content == NULL)
1181+
{
1182+
full_content = apr_psprintf(mptmp, "%s", buf);
1183+
}
1184+
else
1185+
{
1186+
full_content = apr_psprintf(mptmp, "%s%s", full_content, buf);
1187+
}
1188+
}
1189+
fclose(file);
1190+
1191+
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1192+
rvar->value = full_content;
1193+
rvar->value_len = total_lenght;
1194+
rvar->name = apr_psprintf(mptmp, "FILES_TMP_CONTENT:%s",
1195+
log_escape_nq(mptmp, parts[i]->name));
1196+
apr_table_addn(vartab, rvar->name, (void *)rvar);
1197+
1198+
count++;
1199+
}
1200+
}
1201+
}
1202+
1203+
return count;
1204+
}
1205+
1206+
11161207
/* FILES_TMPNAMES */
11171208

11181209
static int var_files_tmpnames_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
@@ -2854,6 +2945,17 @@ void msre_engine_register_default_variables(msre_engine *engine) {
28542945
PHASE_REQUEST_BODY
28552946
);
28562947

2948+
/* FILES_TMP_CONTENT */
2949+
msre_engine_variable_register(engine,
2950+
"FILES_TMP_CONTENT",
2951+
VAR_LIST,
2952+
0, 1,
2953+
var_generic_list_validate,
2954+
var_files_tmp_contents_generate,
2955+
VAR_CACHE,
2956+
PHASE_REQUEST_BODY
2957+
);
2958+
28572959
/* GEO */
28582960
msre_engine_variable_register(engine,
28592961
"GEO",

0 commit comments

Comments
 (0)