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 SecUploadKeepFiles should be set to 'On' in order
to have this collection filled.
This commit is contained in:
Felipe Zimmerle 2013-12-04 23:38:24 -08:00
parent 87df4827dc
commit accb1820e0
2 changed files with 134 additions and 5 deletions

View File

@ -912,11 +912,6 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
}
}
/* Optimisation */
if ((rule->op_name != NULL)&&(strcasecmp(rule->op_name, "inspectFile") == 0)) {
dcfg->upload_validates_files = 1;
}
/* Create skip table if one does not already exist. */
if (dcfg->tmp_rule_placeholders == NULL) {
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,
return NULL;
}
static const char *cmd_upload_save_tmp_files(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
if (strcasecmp(p1, "on") == 0)
{
dcfg->upload_validates_files = 1;
}
else if (strcasecmp(p1, "off") == 0)
{
dcfg->upload_validates_files = 0;
}
else
{
return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for SecTmpSaveUploadedFiles: %s",
p1);
}
return NULL;
}
static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1)
{
directory_config *dcfg = (directory_config *)_dcfg;
@ -3685,6 +3704,14 @@ const command_rec module_directives[] = {
"On or Off"
),
AP_INIT_TAKE1 (
"SecTmpSaveUploadedFiles",
cmd_upload_save_tmp_files,
NULL,
CMD_SCOPE_ANY,
"On or Off"
),
AP_INIT_TAKE1 (
"SecWebAppId",
cmd_web_app_id,

View File

@ -1113,6 +1113,97 @@ static int var_resource_generate(modsec_rec *msr, msre_var *var, msre_rule *rule
return count;
}
/* FILES_TMP_CONTENT */
static int var_files_tmp_contents_generate(modsec_rec *msr, msre_var *var,
msre_rule *rule, apr_table_t *vartab, apr_pool_t *mptmp)
{
multipart_part **parts = NULL;
int i, count = 0;
if (msr->mpd == NULL) return 0;
parts = (multipart_part **)msr->mpd->parts->elts;
for (i = 0; i < msr->mpd->parts->nelts; i++)
{
if ((parts[i]->type == MULTIPART_FILE) &&
(parts[i]->tmp_file_name != NULL))
{
int match = 0;
/* Figure out if we want to include this variable. */
if (var->param == NULL)
{
match = 1;
}
else
{
if (var->param_data != NULL)
{
/* Regex. */
char *my_error_msg = NULL;
if (!(msc_regexec((msc_regex_t *)var->param_data,
parts[i]->name, strlen(parts[i]->name),
&my_error_msg) == PCRE_ERROR_NOMATCH))
{
match = 1;
}
}
else
{
/* Simple comparison. */
if (strcasecmp(parts[i]->name, var->param) == 0)
{
match = 1;
}
}
}
/* If we had a match add this argument to the collection. */
if (match) {
static int buf_size = 1024;
char buf[buf_size];
FILE *file;
size_t nread;
char *full_content = NULL;
size_t total_lenght = 0;
file = fopen(parts[i]->tmp_file_name, "r");
if (file == NULL)
{
continue;
}
while ((nread = fread(buf, 1, buf_size-1, file)) > 0)
{
total_lenght += nread;
buf[nread] = '\0';
if (full_content == NULL)
{
full_content = apr_psprintf(mptmp, "%s", buf);
}
else
{
full_content = apr_psprintf(mptmp, "%s%s", full_content, buf);
}
}
fclose(file);
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
rvar->value = full_content;
rvar->value_len = total_lenght;
rvar->name = apr_psprintf(mptmp, "FILES_TMP_CONTENT:%s",
log_escape_nq(mptmp, parts[i]->name));
apr_table_addn(vartab, rvar->name, (void *)rvar);
count++;
}
}
}
return count;
}
/* FILES_TMPNAMES */
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) {
PHASE_REQUEST_BODY
);
/* FILES_TMP_CONTENT */
msre_engine_variable_register(engine,
"FILES_TMP_CONTENT",
VAR_LIST,
0, 1,
var_generic_list_validate,
var_files_tmp_contents_generate,
VAR_CACHE,
PHASE_REQUEST_BODY
);
/* GEO */
msre_engine_variable_register(engine,
"GEO",