Merge 2.5.x (2.5.12) changes into trunk.
This commit is contained in:
Родитель
ed11e27e0f
Коммит
08edc0c26f
48
CHANGES
48
CHANGES
|
@ -1,5 +1,4 @@
|
|||
|
||||
2 Feb 2010 - trunk
|
||||
04 Feb 2010 - trunk
|
||||
-------------------
|
||||
|
||||
* Add REQUEST_BODY_LENGTH, which contains the number of request body
|
||||
|
@ -27,6 +26,51 @@
|
|||
pave support for allowing access to all ModSecurity variables from
|
||||
mog_log_config. [Ivan Ristic]
|
||||
|
||||
|
||||
04 Feb 2010 - 2.5.12
|
||||
--------------------
|
||||
|
||||
* Fixed SecUploadFileMode to set the correct mode.
|
||||
|
||||
* Fixed nolog,auditlog/noauditlog/nolog controls for disruptive actions.
|
||||
|
||||
* Added additional file info definitions introduced in APR 0.9.5 so that
|
||||
build will work with older APRs (IBM HTTP Server v6).
|
||||
|
||||
* Added SecUploadFileLimit to limit the number of uploaded file parts that
|
||||
will be processed in a multipart POST. The default is 100.
|
||||
|
||||
* Fixed path normalization to better handle backreferences that extend
|
||||
above root directories. Reported by Sogeti/ESEC R&D.
|
||||
|
||||
* Trim whitespace around phrases used with @pmFromFile and allow
|
||||
for both LF and CRLF terminated lines.
|
||||
|
||||
* Allow for more robust parsing for multipart header folding. Reported
|
||||
by Sogeti/ESEC R&D.
|
||||
|
||||
* Fixed failure to match internally set TX variables with regex
|
||||
(TX:/.../) syntax.
|
||||
|
||||
* Fixed failure to log full internal TX variable names and populate
|
||||
MATCHED_VAR* vars.
|
||||
|
||||
* Enabled PCRE "studying" by default. This is now a configure-time option.
|
||||
|
||||
* Added PCRE match limits (SecPcreMatchLimit/SecPcreMatchLimitRecursion) to
|
||||
aide in REDoS type attacks. A rule that goes over the limits will set
|
||||
TX:MSC_PCRE_LIMITS_EXCEEDED. It is intended that the next major release
|
||||
of ModSecurity (2.6.x) will move these flags to a dedicated collection.
|
||||
|
||||
* Reduced default PCRE match limits reducing impact of REDoS on poorly
|
||||
written regex rules. Reported by Sogeti/ESEC R&D.
|
||||
|
||||
* Fixed memory leak in v1 cookie parser. Reported by Sogeti/ESEC R&D.
|
||||
|
||||
* Now support macro expansion in numeric operators (@eq, @ge, @lt, etc.)
|
||||
|
||||
* Update copyright to 2010.
|
||||
|
||||
* Reserved 700,000-799,999 IDs for Ivan Ristic.
|
||||
|
||||
* Fixed SecAction not working when CONNECT request method is used
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
|
||||
ModSecurity for Apache is an open source product, released under terms of
|
||||
the General Public Licence, Version 2 (GPLv2). Please refer to the
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -33,7 +33,8 @@
|
|||
/**
|
||||
* Creates a fresh directory configuration.
|
||||
*/
|
||||
void *create_directory_config(apr_pool_t *mp, char *path) {
|
||||
void *create_directory_config(apr_pool_t *mp, char *path)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)apr_pcalloc(mp, sizeof(directory_config));
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
|
@ -87,6 +88,7 @@ void *create_directory_config(apr_pool_t *mp, char *path) {
|
|||
dcfg->upload_keep_files = NOT_SET;
|
||||
dcfg->upload_validates_files = NOT_SET;
|
||||
dcfg->upload_filemode = NOT_SET;
|
||||
dcfg->upload_file_limit = NOT_SET;
|
||||
|
||||
/* These are only used during the configuration process. */
|
||||
dcfg->tmp_chain_starter = NULL;
|
||||
|
@ -121,8 +123,10 @@ void *create_directory_config(apr_pool_t *mp, char *path) {
|
|||
* Copies rules between one phase of two configuration contexts,
|
||||
* taking exceptions into account.
|
||||
*/
|
||||
static void copy_rules_phase(apr_pool_t *mp, apr_array_header_t *parent_phase_arr,
|
||||
apr_array_header_t *child_phase_arr, apr_array_header_t *exceptions_arr)
|
||||
static void copy_rules_phase(apr_pool_t *mp,
|
||||
apr_array_header_t *parent_phase_arr,
|
||||
apr_array_header_t *child_phase_arr,
|
||||
apr_array_header_t *exceptions_arr)
|
||||
{
|
||||
rule_exception **exceptions;
|
||||
msre_rule **rules;
|
||||
|
@ -190,8 +194,9 @@ static void copy_rules_phase(apr_pool_t *mp, apr_array_header_t *parent_phase_ar
|
|||
* Copies rules between two configuration contexts,
|
||||
* taking exceptions into account.
|
||||
*/
|
||||
static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset, msre_ruleset *child_ruleset,
|
||||
apr_array_header_t *exceptions_arr)
|
||||
static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset,
|
||||
msre_ruleset *child_ruleset,
|
||||
apr_array_header_t *exceptions_arr)
|
||||
{
|
||||
copy_rules_phase(mp, parent_ruleset->phase_request_headers,
|
||||
child_ruleset->phase_request_headers, exceptions_arr);
|
||||
|
@ -210,7 +215,8 @@ static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset, msre_ruleset
|
|||
/**
|
||||
* Merges two directory configurations.
|
||||
*/
|
||||
void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
|
||||
void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
|
||||
{
|
||||
directory_config *parent = (directory_config *)_parent;
|
||||
directory_config *child = (directory_config *)_child;
|
||||
directory_config *merged = create_directory_config(mp, NULL);
|
||||
|
@ -418,6 +424,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
|
|||
? parent->upload_validates_files : child->upload_validates_files);
|
||||
merged->upload_filemode = (child->upload_filemode == NOT_SET
|
||||
? parent->upload_filemode : child->upload_filemode);
|
||||
merged->upload_file_limit = (child->upload_file_limit == NOT_SET
|
||||
? parent->upload_file_limit : child->upload_file_limit);
|
||||
|
||||
/* Misc */
|
||||
merged->data_dir = (child->data_dir == NOT_SET_P
|
||||
|
@ -461,7 +469,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
|
|||
* the configuration phase. It can only be called on copies of those
|
||||
* (created fresh for every transaction).
|
||||
*/
|
||||
void init_directory_config(directory_config *dcfg) {
|
||||
void init_directory_config(directory_config *dcfg)
|
||||
{
|
||||
if (dcfg == NULL) return;
|
||||
|
||||
if (dcfg->is_enabled == NOT_SET) dcfg->is_enabled = 0;
|
||||
|
@ -511,7 +520,8 @@ void init_directory_config(directory_config *dcfg) {
|
|||
if (dcfg->upload_dir == NOT_SET_P) dcfg->upload_dir = NULL;
|
||||
if (dcfg->upload_keep_files == NOT_SET) dcfg->upload_keep_files = KEEP_FILES_OFF;
|
||||
if (dcfg->upload_validates_files == NOT_SET) dcfg->upload_validates_files = 0;
|
||||
if (dcfg->upload_filemode == NOT_SET) dcfg->upload_filemode = mode2fileperms(0600);
|
||||
if (dcfg->upload_filemode == NOT_SET) dcfg->upload_filemode = 0600;
|
||||
if (dcfg->upload_file_limit == NOT_SET) dcfg->upload_file_limit = 100;
|
||||
|
||||
/* Misc */
|
||||
if (dcfg->data_dir == NOT_SET_P) dcfg->data_dir = NULL;
|
||||
|
@ -531,13 +541,14 @@ void init_directory_config(directory_config *dcfg) {
|
|||
if (dcfg->cache_trans_maxitems == (apr_size_t)NOT_SET) dcfg->cache_trans_maxitems = 512;
|
||||
|
||||
if (dcfg->request_encoding == NOT_SET_P) dcfg->request_encoding = NULL;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
||||
const char *p1, const char *p2, const char *p3)
|
||||
const char *p1, const char *p2, const char *p3)
|
||||
{
|
||||
char *my_error_msg = NULL;
|
||||
msre_rule *rule = NULL;
|
||||
|
@ -724,8 +735,8 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
|||
/**
|
||||
*
|
||||
*/
|
||||
static const char *add_marker(cmd_parms *cmd, directory_config *dcfg, const char *p1,
|
||||
const char *p2, const char *p3)
|
||||
static const char *add_marker(cmd_parms *cmd, directory_config *dcfg,
|
||||
const char *p1, const char *p2, const char *p3)
|
||||
{
|
||||
char *my_error_msg = NULL;
|
||||
msre_rule *rule = NULL;
|
||||
|
@ -777,7 +788,7 @@ static const char *add_marker(cmd_parms *cmd, directory_config *dcfg, const char
|
|||
*
|
||||
*/
|
||||
static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
|
||||
const char *p1, const char *p2)
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
char *my_error_msg = NULL;
|
||||
msre_rule *rule = NULL;
|
||||
|
@ -862,17 +873,21 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
|
|||
|
||||
/* -- Configuration directives -- */
|
||||
|
||||
static const char *cmd_action(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_action(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_ACTION, SECACTION_TARGETS, SECACTION_ARGS, p1);
|
||||
}
|
||||
|
||||
static const char *cmd_marker(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_marker(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
const char *action = apr_pstrcat(dcfg->mp, SECMARKER_BASE_ACTIONS, p1, NULL);
|
||||
return add_marker(cmd, (directory_config *)_dcfg, SECMARKER_TARGETS, SECMARKER_ARGS, action);
|
||||
}
|
||||
|
||||
static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (strlen(p1) != 1) {
|
||||
|
@ -884,7 +899,8 @@ static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg, const cha
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = _dcfg;
|
||||
|
||||
if (strcasecmp(p1, "On") == 0) dcfg->auditlog_flag = AUDITLOG_ON;
|
||||
|
@ -899,7 +915,8 @@ static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = _dcfg;
|
||||
|
||||
dcfg->auditlog_name = (char *)p1;
|
||||
|
@ -932,7 +949,8 @@ static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = _dcfg;
|
||||
|
||||
if (dcfg->auditlog_name == NOT_SET_P) {
|
||||
|
@ -969,7 +987,9 @@ static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = _dcfg;
|
||||
|
||||
if (is_valid_parts_specification((char *)p1) != 1) {
|
||||
|
@ -980,7 +1000,9 @@ static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg, const char *
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = _dcfg;
|
||||
|
||||
dcfg->auditlog_relevant_regex = msc_pregcomp(cmd->pool, p1, PCRE_DOTALL, NULL, NULL);
|
||||
|
@ -991,7 +1013,9 @@ static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg, co
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = _dcfg;
|
||||
|
||||
if (strcasecmp(p1, "Serial") == 0) dcfg->auditlog_type = AUDITLOG_SERIAL;
|
||||
|
@ -1004,7 +1028,9 @@ static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg, const char *p
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1024,7 +1050,9 @@ static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg, const char
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1044,7 +1072,9 @@ static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg, const cha
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = _dcfg;
|
||||
|
||||
dcfg->auditlog_storage_dir = ap_server_root_relative(cmd->pool, p1);
|
||||
|
@ -1052,7 +1082,9 @@ static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg, const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (strcmp(p1, "0") == 0) dcfg->cookie_format = COOKIES_V0;
|
||||
|
@ -1065,7 +1097,8 @@ static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg, const char *p1
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
char cwd[1025] = "";
|
||||
|
||||
if (cmd->server->is_virtual) {
|
||||
|
@ -1094,7 +1127,9 @@ static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
|||
/**
|
||||
* Adds component signature to the list of signatures kept in configuration.
|
||||
*/
|
||||
static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
/* ENH Enforce "Name/VersionX.Y.Z (comment)" format. */
|
||||
|
@ -1103,14 +1138,16 @@ static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg, const ch
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_content_injection(cmd_parms *cmd, void *_dcfg, int flag) {
|
||||
static const char *cmd_content_injection(cmd_parms *cmd, void *_dcfg, int flag)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
dcfg->content_injection_enabled = flag;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (cmd->server->is_virtual) {
|
||||
|
@ -1122,7 +1159,8 @@ static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
apr_status_t rc;
|
||||
|
||||
|
@ -1140,7 +1178,9 @@ static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
dcfg->debuglog_level = atoi(p1);
|
||||
|
@ -1149,7 +1189,9 @@ static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg, const char *
|
|||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecDebugLogLevel: %s", p1);
|
||||
}
|
||||
|
||||
static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
extern msc_engine *modsecurity;
|
||||
char *my_error_msg = NULL;
|
||||
|
@ -1213,7 +1255,9 @@ static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg, const char *p
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg, const char *p1, const char *p2) {
|
||||
static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
extern char *guardianlog_name;
|
||||
extern apr_file_t *guardianlog_fd;
|
||||
extern char *guardianlog_condition;
|
||||
|
@ -1262,7 +1306,9 @@ static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg, const char *p1,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
long int limit;
|
||||
|
||||
|
@ -1278,7 +1324,9 @@ static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_request_body_limit(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_request_body_limit(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
long int limit;
|
||||
|
||||
|
@ -1294,7 +1342,9 @@ static const char *cmd_request_body_limit(cmd_parms *cmd, void *_dcfg, const cha
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_request_body_no_files_limit(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_request_body_no_files_limit(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
long int limit;
|
||||
|
||||
|
@ -1310,7 +1360,9 @@ static const char *cmd_request_body_no_files_limit(cmd_parms *cmd, void *_dcfg,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
|
@ -1323,7 +1375,9 @@ static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg, const ch
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
|
@ -1334,7 +1388,9 @@ static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg, const char
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_response_body_access(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_response_body_access(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
|
@ -1347,7 +1403,9 @@ static const char *cmd_response_body_access(cmd_parms *cmd, void *_dcfg, const c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_response_body_limit(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_response_body_limit(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
long int limit;
|
||||
|
||||
|
@ -1365,7 +1423,9 @@ static const char *cmd_response_body_limit(cmd_parms *cmd, void *_dcfg, const ch
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_response_body_limit_action(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_response_body_limit_action(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
|
@ -1378,7 +1438,9 @@ static const char *cmd_response_body_limit_action(cmd_parms *cmd, void *_dcfg, c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg, const char *_p1) {
|
||||
static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg,
|
||||
const char *_p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
char *p1 = apr_pstrdup(cmd->pool, _p1);
|
||||
|
||||
|
@ -1394,7 +1456,9 @@ static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg, cons
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_response_body_mime_types_clear(cmd_parms *cmd, void *_dcfg) {
|
||||
static const char *cmd_response_body_mime_types_clear(cmd_parms *cmd,
|
||||
void *_dcfg)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
|
@ -1407,13 +1471,14 @@ static const char *cmd_response_body_mime_types_clear(cmd_parms *cmd, void *_dcf
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_rule(cmd_parms *cmd, void *_dcfg, const char *p1,
|
||||
const char *p2, const char *p3)
|
||||
static const char *cmd_rule(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1, const char *p2, const char *p3)
|
||||
{
|
||||
return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_NORMAL, p1, p2, p3);
|
||||
}
|
||||
|
||||
static const char *cmd_rule_engine(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_rule_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
|
@ -1428,43 +1493,16 @@ static const char *cmd_rule_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
static const char *cmd_rule_import_by_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
re->type = RULE_EXCEPTION_IMPORT_ID;
|
||||
// TODO verify p1
|
||||
re->param = p1;
|
||||
*(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_rule_import_by_msg(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
re->type = RULE_EXCEPTION_IMPORT_MSG;
|
||||
// TODO verify p1
|
||||
re->param = p1;
|
||||
*(rule_exception **)apr_array_push(dcfg->rule_exceptions) = re;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
static const char *cmd_rule_inheritance(cmd_parms *cmd, void *_dcfg, int flag) {
|
||||
static const char *cmd_rule_inheritance(cmd_parms *cmd, void *_dcfg, int flag)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
dcfg->rule_inheritance = flag;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg, const char *p1,
|
||||
const char *p2)
|
||||
static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
#if defined(WITH_LUA)
|
||||
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
|
||||
|
@ -1475,7 +1513,9 @@ static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg, const char *p1,
|
|||
#endif
|
||||
}
|
||||
|
||||
static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1490,7 +1530,9 @@ static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg, const char
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1514,12 +1556,14 @@ static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg, const cha
|
|||
}
|
||||
|
||||
static const char *cmd_rule_update_action_by_id(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1, const char *p2)
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
return update_rule_action(cmd, (directory_config *)_dcfg, p1, p2);
|
||||
}
|
||||
|
||||
static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
if (cmd->server->is_virtual) {
|
||||
return "ModSecurity: SecServerSignature not allowed in VirtualHost";
|
||||
}
|
||||
|
@ -1527,7 +1571,8 @@ static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg, const char
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_tmp_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_tmp_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1538,7 +1583,8 @@ static const char *cmd_tmp_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_upload_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_upload_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1549,7 +1595,26 @@ static const char *cmd_upload_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_upload_file_limit(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
if (strcasecmp(p1, "default") == 0) {
|
||||
dcfg->upload_file_limit = NOT_SET;
|
||||
}
|
||||
else {
|
||||
dcfg->upload_file_limit = atoi(p1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1569,7 +1634,9 @@ static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg, const char *
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1589,7 +1656,8 @@ static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg, const char
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
/* ENH enforce format (letters, digits, ., _, -) */
|
||||
|
@ -1598,10 +1666,51 @@ static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* PCRE Limits */
|
||||
|
||||
static const char *cmd_pcre_match_limit(cmd_parms *cmd,
|
||||
void *_dcfg, const char *p1)
|
||||
{
|
||||
long val;
|
||||
|
||||
if (cmd->server->is_virtual) {
|
||||
return "ModSecurity: SecPcreMatchLimit not allowed in VirtualHost";
|
||||
}
|
||||
|
||||
val = atol(p1);
|
||||
if (val <= 0) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for "
|
||||
"SecPcreMatchLimit: %s", p1);
|
||||
}
|
||||
msc_pcre_match_limit = (unsigned long int)val;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_pcre_match_limit_recursion(cmd_parms *cmd,
|
||||
void *_dcfg, const char *p1)
|
||||
{
|
||||
long val;
|
||||
|
||||
if (cmd->server->is_virtual) {
|
||||
return "ModSecurity: SecPcreMatchLimitRecursion not allowed in VirtualHost";
|
||||
}
|
||||
|
||||
val = atol(p1);
|
||||
if (val <= 0) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for "
|
||||
"SecPcreMatchLimitRecursion: %s", p1);
|
||||
}
|
||||
msc_pcre_match_limit_recursion = (unsigned long int)val;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* -- Geo Lookup configuration -- */
|
||||
|
||||
static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
const char *p1)
|
||||
{
|
||||
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
|
||||
char *error_msg;
|
||||
|
@ -1618,7 +1727,9 @@ static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
|
|||
|
||||
/* -- Cache -- */
|
||||
|
||||
static const char *cmd_cache_transformations(cmd_parms *cmd, void *_dcfg, const char *p1, const char *p2) {
|
||||
static const char *cmd_cache_transformations(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
@ -1911,6 +2022,22 @@ const command_rec module_directives[] = {
|
|||
"marker for a skipAfter target"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecPcreMatchLimit",
|
||||
cmd_pcre_match_limit,
|
||||
NULL,
|
||||
CMD_SCOPE_MAIN,
|
||||
"PCRE match limit"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecPcreMatchLimitRecursion",
|
||||
cmd_pcre_match_limit_recursion,
|
||||
NULL,
|
||||
CMD_SCOPE_MAIN,
|
||||
"PCRE match limit recursion"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecRequestBodyAccess",
|
||||
cmd_request_body_access,
|
||||
|
@ -2071,6 +2198,14 @@ const command_rec module_directives[] = {
|
|||
"path to the file upload area"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecUploadFileLimit",
|
||||
cmd_upload_file_limit,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"limit the number of uploaded files processed"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecUploadFileMode",
|
||||
cmd_upload_filemode,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -694,6 +694,9 @@ SHELL'
|
|||
ac_subst_files=''
|
||||
ac_user_opts='
|
||||
enable_option_checking
|
||||
enable_pcre_study
|
||||
enable_pcre_match_limit
|
||||
enable_pcre_match_limit_recursion
|
||||
enable_errors
|
||||
enable_verbose_output
|
||||
enable_strict_compile
|
||||
|
@ -1328,6 +1331,12 @@ Optional Features:
|
|||
--disable-option-checking ignore unrecognized --enable/--with options
|
||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--enable-pcre-study Enable PCRE regex studying during configure.
|
||||
--enable-pcre-match-limit
|
||||
Enable PCRE regex match limit during configure.
|
||||
--enable-pcre-match-limit-recursion
|
||||
Enable PCRE regex match limit recursion during
|
||||
configure.
|
||||
--disable-errors Disable errors during configure.
|
||||
--enable-verbose-output Enable more verbose configure output.
|
||||
--enable-strict-compile Enable strict compilation (warnings are errors).
|
||||
|
@ -4186,7 +4195,7 @@ test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
|
|||
esac
|
||||
|
||||
|
||||
for ac_func in atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol
|
||||
for ac_func in atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol fchmod
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
|
@ -4221,6 +4230,62 @@ MSC_REGRESSION_DOCROOT_DIR="$MSC_REGRESSION_SERVERROOT_DIR/htdocs"
|
|||
|
||||
### Configure Options
|
||||
|
||||
# Add PCRE Studying
|
||||
|
||||
# Check whether --enable-pcre-study was given.
|
||||
if test "${enable_pcre_study+set}" = set; then :
|
||||
enableval=$enable_pcre_study;
|
||||
if test "$enableval" != "no"; then
|
||||
pcre_study='-DWITH_PCRE_STUDY'
|
||||
else
|
||||
pcre_study=''
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
pcre_study='-DWITH_PCRE_STUDY'
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Limit PCRE matching
|
||||
# Check whether --enable-pcre-match-limit was given.
|
||||
if test "${enable_pcre_match_limit+set}" = set; then :
|
||||
enableval=$enable_pcre_match_limit;
|
||||
if test "$enableval" = "yes"; then
|
||||
as_fn_error "PCRE match limits require a numeric value" "$LINENO" 5
|
||||
elif test "$enableval" = "no"; then
|
||||
pcre_match_limit=''
|
||||
else
|
||||
pcre_match_limit="-DMODSEC_PCRE_MATCH_LIMIT=$enableval"
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
pcre_match_limit='-DMODSEC_PCRE_MATCH_LIMIT=1500'
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Limit PCRE matching recursion
|
||||
# Check whether --enable-pcre-match-limit-recursion was given.
|
||||
if test "${enable_pcre_match_limit_recursion+set}" = set; then :
|
||||
enableval=$enable_pcre_match_limit_recursion;
|
||||
if test "$enableval" = "yes"; then
|
||||
as_fn_error "PCRE match limits require a numeric value" "$LINENO" 5
|
||||
elif test "$enableval" = "no"; then
|
||||
pcre_match_limit_recursion=''
|
||||
else
|
||||
pcre_match_limit_recursion="-DMODSEC_PCRE_MATCH_LIMIT_RECURSION=$enableval"
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
pcre_match_limit_recursion='-DMODSEC_PCRE_MATCH_LIMIT_RECURSION=1500'
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Ignore configure errors
|
||||
# Check whether --enable-errors was given.
|
||||
if test "${enable_errors+set}" = set; then :
|
||||
|
@ -4575,7 +4640,7 @@ else
|
|||
EXTRA_CFLAGS="-O2 -g -Wall $strict_compile"
|
||||
fi
|
||||
fi
|
||||
MODSEC_EXTRA_CFLAGS="$debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api"
|
||||
MODSEC_EXTRA_CFLAGS="$pcre_study $pcre_match_limit $pcre_match_limit_recursion $debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api"
|
||||
|
||||
APXS_WRAPPER=build/apxs-wrapper
|
||||
APXS_EXTRA_CFLAGS=""
|
||||
|
|
|
@ -40,7 +40,7 @@ AC_TYPE_UINT8_T
|
|||
# Checks for library functions.
|
||||
AC_FUNC_MALLOC
|
||||
AC_FUNC_MEMCMP
|
||||
AC_CHECK_FUNCS([atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol])
|
||||
AC_CHECK_FUNCS([atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol fchmod])
|
||||
|
||||
# Some directories
|
||||
MSC_BASE_DIR=`pwd`
|
||||
|
@ -63,6 +63,56 @@ AC_SUBST(MSC_REGRESSION_DOCROOT_DIR)
|
|||
|
||||
### Configure Options
|
||||
|
||||
# Add PCRE Studying
|
||||
|
||||
AC_ARG_ENABLE(pcre-study,
|
||||
AS_HELP_STRING([--enable-pcre-study],
|
||||
[Enable PCRE regex studying during configure.]),
|
||||
[
|
||||
if test "$enableval" != "no"; then
|
||||
pcre_study='-DWITH_PCRE_STUDY'
|
||||
else
|
||||
pcre_study=''
|
||||
fi
|
||||
],
|
||||
[
|
||||
pcre_study='-DWITH_PCRE_STUDY'
|
||||
])
|
||||
|
||||
# Limit PCRE matching
|
||||
AC_ARG_ENABLE(pcre-match-limit,
|
||||
AS_HELP_STRING([--enable-pcre-match-limit],
|
||||
[Enable PCRE regex match limit during configure.]),
|
||||
[
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_MSG_ERROR([PCRE match limits require a numeric value])
|
||||
elif test "$enableval" = "no"; then
|
||||
pcre_match_limit=''
|
||||
else
|
||||
pcre_match_limit="-DMODSEC_PCRE_MATCH_LIMIT=$enableval"
|
||||
fi
|
||||
],
|
||||
[
|
||||
pcre_match_limit='-DMODSEC_PCRE_MATCH_LIMIT=1500'
|
||||
])
|
||||
|
||||
# Limit PCRE matching recursion
|
||||
AC_ARG_ENABLE(pcre-match-limit-recursion,
|
||||
AS_HELP_STRING([--enable-pcre-match-limit-recursion],
|
||||
[Enable PCRE regex match limit recursion during configure.]),
|
||||
[
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_MSG_ERROR([PCRE match limits require a numeric value])
|
||||
elif test "$enableval" = "no"; then
|
||||
pcre_match_limit_recursion=''
|
||||
else
|
||||
pcre_match_limit_recursion="-DMODSEC_PCRE_MATCH_LIMIT_RECURSION=$enableval"
|
||||
fi
|
||||
],
|
||||
[
|
||||
pcre_match_limit_recursion='-DMODSEC_PCRE_MATCH_LIMIT_RECURSION=1500'
|
||||
])
|
||||
|
||||
# Ignore configure errors
|
||||
AC_ARG_ENABLE(errors,
|
||||
AS_HELP_STRING([--disable-errors],
|
||||
|
@ -325,7 +375,7 @@ else
|
|||
EXTRA_CFLAGS="-O2 -g -Wall $strict_compile"
|
||||
fi
|
||||
fi
|
||||
MODSEC_EXTRA_CFLAGS="$debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api"
|
||||
MODSEC_EXTRA_CFLAGS="$pcre_study $pcre_match_limit $pcre_match_limit_recursion $debug_conf $debug_cache $debug_acmp $debug_mem $perf_meas $modsec_api"
|
||||
|
||||
APXS_WRAPPER=build/apxs-wrapper
|
||||
APXS_EXTRA_CFLAGS=""
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -52,6 +52,9 @@ apr_file_t DSOLOCAL *guardianlog_fd = NULL;
|
|||
|
||||
char DSOLOCAL *guardianlog_condition = NULL;
|
||||
|
||||
unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
|
||||
|
||||
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
|
||||
|
||||
/* -- Miscellaneous functions -- */
|
||||
|
||||
|
@ -227,9 +230,24 @@ int perform_interception(modsec_rec *msr) {
|
|||
break;
|
||||
}
|
||||
|
||||
/* If the level is not high enough to add an alert message, but "auditlog"
|
||||
* is enabled, then still add the message. */
|
||||
if ((log_level > 3) && (actionset->auditlog != 0)) {
|
||||
*(const char **)apr_array_push(msr->alerts) = msc_alert_message(msr, actionset, NULL, message);
|
||||
}
|
||||
|
||||
/* Log the message now. */
|
||||
msc_alert(msr, log_level, actionset, message, msr->intercept_message);
|
||||
|
||||
/* However, this will mark the txn relevant again if it is <= 3,
|
||||
* which will mess up noauditlog. We need to compensate for this
|
||||
* so that we do not increment twice when auditlog is enabled and
|
||||
* prevent incrementing when auditlog is disabled.
|
||||
*/
|
||||
if ((actionset->auditlog == 0) && (log_level <= 3)) {
|
||||
msr->is_relevant--;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
/* Define to 1 if you have the `atexit' function. */
|
||||
#undef HAVE_ATEXIT
|
||||
|
||||
/* Define to 1 if you have the `fchmod' function. */
|
||||
#undef HAVE_FCHMOD
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -127,6 +127,10 @@ extern module AP_MODULE_DECLARE_DATA security2_module;
|
|||
|
||||
extern DSOLOCAL const command_rec module_directives[];
|
||||
|
||||
extern DSOLOCAL unsigned long int msc_pcre_match_limit;
|
||||
|
||||
extern DSOLOCAL unsigned long int msc_pcre_match_limit_recursion;
|
||||
|
||||
#define RESBODY_STATUS_NOT_READ 0 /* we were not configured to read the body */
|
||||
#define RESBODY_STATUS_ERROR 1 /* error occured while we were reading the body */
|
||||
#define RESBODY_STATUS_PARTIAL 2 /* partial body content available in the brigade */
|
||||
|
@ -335,6 +339,7 @@ struct modsec_rec {
|
|||
/* upload */
|
||||
int upload_extract_files;
|
||||
int upload_remove_files;
|
||||
int upload_files_count;
|
||||
|
||||
/* other */
|
||||
apr_table_t *collections_original;
|
||||
|
@ -441,6 +446,7 @@ struct directory_config {
|
|||
int upload_keep_files;
|
||||
int upload_validates_files;
|
||||
int upload_filemode; /* int only so NOT_SET works */
|
||||
int upload_file_limit;
|
||||
|
||||
/* Used only in the configuration phase. */
|
||||
msre_rule *tmp_chain_starter;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -279,12 +279,20 @@ static int multipart_process_part_header(modsec_rec *msr, char **error_msg) {
|
|||
} else {
|
||||
/* Header line. */
|
||||
|
||||
if ((msr->mpd->buf[0] == '\t') || (msr->mpd->buf[0] == ' ')) {
|
||||
if (isspace(msr->mpd->buf[0])) {
|
||||
char *header_value, *new_value, *data;
|
||||
|
||||
/* header folding, add data to the header we are building */
|
||||
msr->mpd->flag_header_folding = 1;
|
||||
|
||||
/* RFC-2557 states header folding is SP / HTAB, but PHP and
|
||||
* perhaps others will take any whitespace. So, we accept,
|
||||
* but with a flag set.
|
||||
*/
|
||||
if ((msr->mpd->buf[0] != '\t') && (msr->mpd->buf[0] != ' ')) {
|
||||
msr->mpd->flag_invalid_header_folding = 1;
|
||||
}
|
||||
|
||||
if (msr->mpd->mpp->last_header_name == NULL) {
|
||||
/* we are not building a header at this moment */
|
||||
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid part header (folding error).");
|
||||
|
@ -293,7 +301,15 @@ static int multipart_process_part_header(modsec_rec *msr, char **error_msg) {
|
|||
|
||||
/* locate the beginning of data */
|
||||
data = msr->mpd->buf;
|
||||
while((*data == '\t') || (*data == ' ')) data++;
|
||||
while(isspace(*data)) {
|
||||
/* Flag invalid header folding if an invalid RFC-2557 character is used anywhere
|
||||
* in the folding prefix.
|
||||
*/
|
||||
if ((*data != '\t') && (*data != ' ')) {
|
||||
msr->mpd->flag_invalid_header_folding = 1;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
|
||||
new_value = apr_pstrdup(msr->mp, data);
|
||||
remove_lf_crlf_inplace(new_value);
|
||||
|
@ -397,16 +413,32 @@ static int multipart_process_part_data(modsec_rec *msr, char **error_msg) {
|
|||
|
||||
/* add data to the part we are building */
|
||||
if (msr->mpd->mpp->type == MULTIPART_FILE) {
|
||||
int extract = msr->upload_extract_files;
|
||||
|
||||
/* remember where we started */
|
||||
if (msr->mpd->mpp->length == 0) {
|
||||
msr->mpd->mpp->offset = msr->mpd->buf_offset;
|
||||
}
|
||||
|
||||
/* check if the file limit has been reached */
|
||||
if (extract && (msr->mpd->nfiles >= msr->txcfg->upload_file_limit)) {
|
||||
if (msr->mpd->flag_file_limit_exceeded == 0) {
|
||||
*error_msg = apr_psprintf(msr->mp,
|
||||
"Multipart: Upload file limit exceeded "
|
||||
"SecUploadFileLimit %d.",
|
||||
msr->txcfg->upload_file_limit);
|
||||
msr_log(msr, 3, "%s", *error_msg);
|
||||
|
||||
msr->mpd->flag_file_limit_exceeded = 1;
|
||||
}
|
||||
|
||||
extract = 0;
|
||||
}
|
||||
|
||||
/* only store individual files on disk if we are going
|
||||
* to keep them or if we need to have them approved later
|
||||
*/
|
||||
if (msr->upload_extract_files) {
|
||||
if (extract) {
|
||||
/* first create a temporary file if we don't have it already */
|
||||
if (msr->mpd->mpp->tmp_file_fd == 0) {
|
||||
/* construct temporary file name */
|
||||
|
@ -421,8 +453,14 @@ static int multipart_process_part_data(modsec_rec *msr, char **error_msg) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* keep track of the files count */
|
||||
msr->mpd->nfiles++;
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Multipart: Created temporary file: %s",
|
||||
msr_log(msr, 4,
|
||||
"Multipart: Created temporary file %d (mode %04o): %s",
|
||||
msr->mpd->nfiles,
|
||||
(unsigned int)msr->txcfg->upload_filemode,
|
||||
log_escape_nq(msr->mp, msr->mpd->mpp->tmp_file_name));
|
||||
}
|
||||
}
|
||||
|
@ -879,6 +917,14 @@ int multipart_complete(modsec_rec *msr, char **error_msg) {
|
|||
if (msr->mpd->flag_missing_semicolon) {
|
||||
msr_log(msr, 4, "Multipart: Warning: missing semicolon in C-T header.");
|
||||
}
|
||||
|
||||
if (msr->mpd->flag_invalid_quoting) {
|
||||
msr_log(msr, 4, "Multipart: Warning: invalid quoting used.");
|
||||
}
|
||||
|
||||
if (msr->mpd->flag_invalid_header_folding) {
|
||||
msr_log(msr, 4, "Multipart: Warning: invalid header folding used.");
|
||||
}
|
||||
}
|
||||
|
||||
if ((msr->mpd->seen_data != 0) && (msr->mpd->is_complete == 0)) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -68,6 +68,9 @@ struct multipart_data {
|
|||
/* this array keeps parts */
|
||||
apr_array_header_t *parts;
|
||||
|
||||
/* Number of parts that are files */
|
||||
int nfiles;
|
||||
|
||||
/* mime boundary used to detect when
|
||||
* parts end and begin
|
||||
*/
|
||||
|
@ -118,6 +121,8 @@ struct multipart_data {
|
|||
int flag_boundary_whitespace;
|
||||
int flag_missing_semicolon;
|
||||
int flag_invalid_quoting;
|
||||
int flag_invalid_header_folding;
|
||||
int flag_file_limit_exceeded;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -22,7 +22,9 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
int parse_cookies_v0(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies) {
|
||||
int parse_cookies_v0(modsec_rec *msr, char *_cookie_header,
|
||||
apr_table_t *cookies)
|
||||
{
|
||||
char *attr_name = NULL, *attr_value = NULL;
|
||||
char *cookie_header;
|
||||
char *saveptr = NULL;
|
||||
|
@ -85,13 +87,21 @@ int parse_cookies_v0(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies
|
|||
/**
|
||||
*
|
||||
*/
|
||||
int parse_cookies_v1(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies) {
|
||||
int parse_cookies_v1(modsec_rec *msr, char *_cookie_header,
|
||||
apr_table_t *cookies)
|
||||
{
|
||||
char *attr_name = NULL, *attr_value = NULL, *p = NULL;
|
||||
char *prev_attr_name = NULL;
|
||||
char *cookie_header = NULL;
|
||||
int cookie_count = 0;
|
||||
|
||||
if (_cookie_header == NULL) return -1;
|
||||
// XXX Should it not match _v0 parser?
|
||||
//if (_cookie_header == NULL) {
|
||||
// msr_log(msr, 1, "Cookie parser: Received null for argument.");
|
||||
// return -1;
|
||||
//}
|
||||
|
||||
cookie_header = strdup(_cookie_header);
|
||||
if (cookie_header == NULL) return -1;
|
||||
|
||||
|
@ -213,6 +223,7 @@ int parse_cookies_v1(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies
|
|||
while( (*p != 0)&&( (*p == ',')||(*p == ';')||(isspace(*p)) ) ) p++;
|
||||
}
|
||||
|
||||
free(cookie_header);
|
||||
return cookie_count;
|
||||
}
|
||||
|
||||
|
@ -322,7 +333,8 @@ int parse_arguments(modsec_rec *msr, const char *s, apr_size_t inputlength,
|
|||
/**
|
||||
*
|
||||
*/
|
||||
void add_argument(modsec_rec *msr, apr_table_t *arguments, msc_arg *arg) {
|
||||
void add_argument(modsec_rec *msr, apr_table_t *arguments, msc_arg *arg)
|
||||
{
|
||||
if (msr->txcfg->debuglog_level >= 5) {
|
||||
msr_log(msr, 5, "Adding request argument (%s): name \"%s\", value \"%s\"",
|
||||
arg->origin, log_escape_ex(msr->mp, arg->name, arg->name_len),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -38,17 +38,21 @@ apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Compiles the provided regular expression pattern. The last two
|
||||
* Compiles the provided regular expression pattern. The _err*
|
||||
* parameters are optional, but if they are provided and an error
|
||||
* occurs they will contain the error message and the offset in
|
||||
* the pattern where the offending part of the pattern begins.
|
||||
* the pattern where the offending part of the pattern begins. The
|
||||
* match_limit* parameters are optional and if >0, then will set
|
||||
* match limits.
|
||||
*/
|
||||
void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
|
||||
const char **_errptr, int *_erroffset)
|
||||
void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
|
||||
const char **_errptr, int *_erroffset,
|
||||
int match_limit, int match_limit_recursion)
|
||||
{
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
msc_regex_t *regex;
|
||||
pcre_extra *pe = NULL;
|
||||
|
||||
regex = apr_pcalloc(pool, sizeof(msc_regex_t));
|
||||
if (regex == NULL) return NULL;
|
||||
|
@ -62,15 +66,74 @@ void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
|
|||
if (regex->re == NULL) return NULL;
|
||||
|
||||
#ifdef WITH_PCRE_STUDY
|
||||
regex->pe = pcre_study(regex->re, 0, &errptr);
|
||||
pe = pcre_study(regex->re, 0, &errptr);
|
||||
#endif
|
||||
|
||||
/* Setup the pcre_extra record if pcre_study did not already do it */
|
||||
if (pe == NULL) {
|
||||
pe = malloc(sizeof(pcre_extra));
|
||||
if (pe == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(pe, 0, sizeof(pcre_extra));
|
||||
}
|
||||
|
||||
#ifdef PCRE_EXTRA_MATCH_LIMIT
|
||||
/* If match limit is available, then use it */
|
||||
|
||||
/* Use ModSecurity runtime defaults */
|
||||
if (match_limit > 0) {
|
||||
pe->match_limit = match_limit;
|
||||
pe->flags |= PCRE_EXTRA_MATCH_LIMIT;
|
||||
}
|
||||
#ifdef MODSEC_PCRE_MATCH_LIMIT
|
||||
/* Default to ModSecurity compiled defaults */
|
||||
else {
|
||||
pe->match_limit = MODSEC_PCRE_MATCH_LIMIT;
|
||||
pe->flags |= PCRE_EXTRA_MATCH_LIMIT;
|
||||
}
|
||||
#endif /* MODSEC_PCRE_MATCH_LIMIT */
|
||||
#else
|
||||
#warning This PCRE version does not support match limits! Upgrade to at least PCRE v6.5.
|
||||
#endif /* PCRE_EXTRA_MATCH_LIMIT */
|
||||
|
||||
#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
|
||||
/* If match limit recursion is available, then use it */
|
||||
|
||||
/* Use ModSecurity runtime defaults */
|
||||
if (match_limit_recursion > 0) {
|
||||
pe->match_limit_recursion = match_limit_recursion;
|
||||
pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
|
||||
}
|
||||
#ifdef MODSEC_PCRE_MATCH_LIMIT_RECURSION
|
||||
/* Default to ModSecurity compiled defaults */
|
||||
else {
|
||||
pe->match_limit_recursion = MODSEC_PCRE_MATCH_LIMIT_RECURSION;
|
||||
pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
|
||||
}
|
||||
#endif /* MODSEC_PCRE_MATCH_LIMIT_RECURSION */
|
||||
#else
|
||||
#warning This PCRE version does not support match recursion limits! Upgrade to at least PCRE v6.5.
|
||||
#endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
|
||||
|
||||
regex->pe = pe;
|
||||
|
||||
apr_pool_cleanup_register(pool, (void *)regex,
|
||||
(apr_status_t (*)(void *))msc_pcre_cleanup, apr_pool_cleanup_null);
|
||||
|
||||
return regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the provided regular expression pattern. Calls msc_pregcomp_ex()
|
||||
* with default limits.
|
||||
*/
|
||||
void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
|
||||
const char **_errptr, int *_erroffset)
|
||||
{
|
||||
return msc_pregcomp_ex(pool, pattern, options, _errptr, _erroffset, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes regular expression with extended options.
|
||||
* Returns PCRE_ERROR_NOMATCH when there is no match, error code < -1
|
||||
|
@ -119,3 +182,4 @@ int msc_fullinfo(msc_regex_t *regex, int what, void *where)
|
|||
{
|
||||
return pcre_fullinfo(regex->re, regex->pe, what, where);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -22,6 +22,17 @@
|
|||
typedef struct msc_regex_t msc_regex_t;
|
||||
|
||||
#include "pcre.h"
|
||||
|
||||
#ifndef PCRE_ERROR_MATCHLIMIT
|
||||
/* Define for compile, but not valid in this version of PCRE. */
|
||||
#define PCRE_ERROR_MATCHLIMIT (-8)
|
||||
#endif /* PCRE_ERROR_MATCHLIMIT */
|
||||
|
||||
#ifndef PCRE_ERROR_RECURSIONLIMIT
|
||||
/* Define for compile, but not valid in this version of PCRE. */
|
||||
#define PCRE_ERROR_RECURSIONLIMIT (-21)
|
||||
#endif /* PCRE_ERROR_RECURSIONLIMIT */
|
||||
|
||||
#include "apr_general.h"
|
||||
#include "modsecurity.h"
|
||||
|
||||
|
@ -33,17 +44,23 @@ struct msc_regex_t {
|
|||
|
||||
apr_status_t DSOLOCAL msc_pcre_cleanup(msc_regex_t *regex);
|
||||
|
||||
void DSOLOCAL *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
|
||||
const char **_errptr, int *_erroffset);
|
||||
void DSOLOCAL *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
|
||||
const char **_errptr, int *_erroffset,
|
||||
int match_limit, int match_limit_recursion);
|
||||
|
||||
int DSOLOCAL msc_regexec_ex(msc_regex_t *regex, const char *s, unsigned int slen,
|
||||
int startoffset, int options, int *ovector, int ovecsize, char **error_msg);
|
||||
void DSOLOCAL *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
|
||||
const char **_errptr, int *_erroffset);
|
||||
|
||||
int DSOLOCAL msc_regexec_ex(msc_regex_t *regex, const char *s,
|
||||
unsigned int slen, int startoffset, int options,
|
||||
int *ovector, int ovecsize, char **error_msg);
|
||||
|
||||
int DSOLOCAL msc_regexec_capture(msc_regex_t *regex, const char *s,
|
||||
unsigned int slen, int *ovector, int ovecsize, char **error_msg);
|
||||
unsigned int slen, int *ovector,
|
||||
int ovecsize, char **error_msg);
|
||||
|
||||
int DSOLOCAL msc_regexec(msc_regex_t *regex, const char *s, unsigned int slen,
|
||||
char **error_msg);
|
||||
int DSOLOCAL msc_regexec(msc_regex_t *regex, const char *s,
|
||||
unsigned int slen, char **error_msg);
|
||||
|
||||
int DSOLOCAL msc_fullinfo(msc_regex_t *regex, int what, void *where);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -79,7 +79,8 @@ static apr_pool_t *g_mp = NULL;
|
|||
static modsec_rec *g_msr = NULL;
|
||||
static unsigned char buf[BUFLEN];
|
||||
msc_engine *modsecurity = NULL;
|
||||
|
||||
unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
|
||||
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
|
||||
|
||||
/* Stubs */
|
||||
char *format_error_log_message(apr_pool_t *mp, error_message *em) {
|
||||
|
@ -765,7 +766,7 @@ int main(int argc, const char * const argv[])
|
|||
result = RESULT_WRONGRET;
|
||||
}
|
||||
else if (param_len != out_len) {
|
||||
fprintf(stderr, "Lenth %" APR_SIZE_T_FMT " (expected %" APR_SIZE_T_FMT ")\n", out_len, param_len);
|
||||
fprintf(stderr, "Length %" APR_SIZE_T_FMT " (expected %" APR_SIZE_T_FMT ")\n", out_len, param_len);
|
||||
result = RESULT_WRONGSIZE;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -16,15 +16,16 @@
|
|||
* directly using the email address support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include "msc_release.h"
|
||||
#include "msc_util.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "mod_security2_config.h"
|
||||
#include "msc_release.h"
|
||||
#include "msc_util.h"
|
||||
|
||||
#include <apr_lib.h>
|
||||
|
||||
/**
|
||||
|
@ -435,14 +436,25 @@ char *current_filetime(apr_pool_t *mp) {
|
|||
*
|
||||
*/
|
||||
int msc_mkstemp_ex(char *template, int mode) {
|
||||
int fd = -1;
|
||||
|
||||
/* ENH Use apr_file_mktemp instead. */
|
||||
|
||||
#if !(defined(WIN32)||defined(NETWARE))
|
||||
return mkstemp(template);
|
||||
#else
|
||||
#if !(defined(WIN32)||defined(NETWARE))
|
||||
fd = mkstemp(template);
|
||||
#ifdef HAVE_FCHMOD
|
||||
if ((fd != -1) && (mode != 0)) {
|
||||
if (fchmod(fd, mode) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_FCHMOD */
|
||||
#else
|
||||
if (mktemp(template) == NULL) return -1;
|
||||
return open(template, O_WRONLY | O_APPEND | O_CREAT | O_BINARY, mode);
|
||||
#endif
|
||||
fd = open(template, O_WRONLY | O_APPEND | O_CREAT | O_BINARY, mode);
|
||||
#endif /* !(defined(WIN32)||defined(NETWARE)) */
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1149,68 +1161,175 @@ int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len) {
|
|||
* IMP1 Assumes NUL-terminated
|
||||
*/
|
||||
int normalize_path_inplace(unsigned char *input, int input_len, int win, int *changed) {
|
||||
unsigned char *d = input;
|
||||
int i, count;
|
||||
unsigned char *src;
|
||||
unsigned char *dst;
|
||||
unsigned char *end;
|
||||
int ldst = 0;
|
||||
int hitroot = 0;
|
||||
int done = 0;
|
||||
int relative;
|
||||
int trailing;
|
||||
|
||||
*changed = 0;
|
||||
|
||||
i = count = 0;
|
||||
while ((i < input_len)&&(count < input_len)) {
|
||||
char c = input[i];
|
||||
/* Need at least one byte to normalize */
|
||||
if (input_len <= 0) return 0;
|
||||
|
||||
/*
|
||||
* ENH: Deal with UNC and drive letters?
|
||||
*/
|
||||
|
||||
src = dst = input;
|
||||
end = input + (input_len - 1);
|
||||
ldst = 1;
|
||||
|
||||
relative = ((*input == '/') || (win && (*input == '\\'))) ? 0 : 1;
|
||||
trailing = ((*end == '/') || (win && (*end == '\\'))) ? 1 : 0;
|
||||
|
||||
|
||||
while (!done && (src <= end) && (dst <= end)) {
|
||||
/* Convert backslash to forward slash on Windows only. */
|
||||
if ((win)&&(c == '\\')) {
|
||||
c = '/';
|
||||
*changed = 1;
|
||||
}
|
||||
|
||||
if (c == '/') {
|
||||
/* Is there a directory back-reference? Yes, we
|
||||
* require at least 5 prior bytes here. That's on
|
||||
* purpose.
|
||||
*/
|
||||
if ((count >= 5)&&(*(d - 1) == '.')&&(*(d - 2) == '.')&&(*(d - 3) == '/')) {
|
||||
unsigned char *cd = d - 4;
|
||||
int ccount = count - 4;
|
||||
|
||||
if (win) {
|
||||
if (*src == '\\') {
|
||||
*src = '/';
|
||||
*changed = 1;
|
||||
|
||||
/* Go back until we reach the beginning or a forward slash. */
|
||||
while ((ccount > 0)&&(*cd != '/')) {
|
||||
ccount--;
|
||||
cd--;
|
||||
}
|
||||
|
||||
if (*cd == '/') {
|
||||
d = cd;
|
||||
count = ccount;
|
||||
}
|
||||
} else
|
||||
/* Is there a directory self-reference? */
|
||||
if ((count >= 2)&&(*(d - 1) == '.')&&(*(d - 2) == '/')) {
|
||||
/* Ignore the last two bytes. */
|
||||
d -= 2;
|
||||
count -= 2;
|
||||
*changed = 1;
|
||||
} else
|
||||
/* Or are there just multiple occurences of forward slash? */
|
||||
if ((count >= 1)&&(*(d - 1) == '/')) {
|
||||
/* Ignore the last one byte. */
|
||||
d--;
|
||||
count--;
|
||||
}
|
||||
if ((src < end) && (*(src + 1) == '\\')) {
|
||||
*(src + 1) = '/';
|
||||
*changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the byte over. */
|
||||
*d++ = c;
|
||||
count++;
|
||||
i++;
|
||||
/* Always normalize at the end of the input. */
|
||||
if (src == end) {
|
||||
done = 1;
|
||||
}
|
||||
|
||||
/* Skip normalization if this is NOT the end of the path segment. */
|
||||
else if (*(src + 1) != '/') {
|
||||
goto copy; /* Skip normalization. */
|
||||
}
|
||||
|
||||
/*** Normalize the path segment. ***/
|
||||
|
||||
/* Could it be an empty path segment? */
|
||||
if ((src != end) && *src == '/') {
|
||||
/* Ignore */
|
||||
*changed = 1;
|
||||
goto copy; /* Copy will take care of this. */
|
||||
}
|
||||
|
||||
/* Could it be a back or self reference? */
|
||||
else if (*src == '.') {
|
||||
|
||||
/* Back-reference? */
|
||||
if ((dst > input) && (*(dst - 1) == '.')) {
|
||||
/* If a relative path and either our normalization has
|
||||
* already hit the rootdir, or this is a backref with no
|
||||
* previous path segment, then mark that the rootdir was hit
|
||||
* and just copy the backref as no normilization is possible.
|
||||
*/
|
||||
if (relative && (hitroot || ((dst - 2) <= input))) {
|
||||
hitroot = 1;
|
||||
|
||||
goto copy; /* Skip normalization. */
|
||||
}
|
||||
|
||||
/* Remove backreference and the previous path segment. */
|
||||
dst -= 3;
|
||||
while ((dst > input) && (*dst != '/')) {
|
||||
dst--;
|
||||
}
|
||||
|
||||
/* But do not allow going above rootdir. */
|
||||
if (dst <= input) {
|
||||
hitroot = 1;
|
||||
dst = input;
|
||||
|
||||
/* Need to leave the root slash if this
|
||||
* is not a relative path and the end was reached
|
||||
* on a backreference.
|
||||
*/
|
||||
if (!relative && (src == end)) {
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
if (done) goto length; /* Skip the copy. */
|
||||
src++;
|
||||
|
||||
*changed = 1;
|
||||
}
|
||||
|
||||
/* Relative Self-reference? */
|
||||
else if (dst == input) {
|
||||
*changed = 1;
|
||||
|
||||
/* Ignore. */
|
||||
|
||||
if (done) goto length; /* Skip the copy. */
|
||||
src++;
|
||||
}
|
||||
|
||||
/* Self-reference? */
|
||||
else if (*(dst - 1) == '/') {
|
||||
*changed = 1;
|
||||
|
||||
/* Ignore. */
|
||||
|
||||
if (done) goto length; /* Skip the copy. */
|
||||
dst--;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Found a regular path segment. */
|
||||
else if (dst > input) {
|
||||
hitroot = 0;
|
||||
}
|
||||
|
||||
copy:
|
||||
/*** Copy the byte if required. ***/
|
||||
|
||||
/* Skip to the last forward slash when multiple are used. */
|
||||
if (*src == '/') {
|
||||
unsigned char *oldsrc = src;
|
||||
|
||||
while ( (src < end)
|
||||
&& ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) )
|
||||
{
|
||||
src++;
|
||||
}
|
||||
if (oldsrc != src) *changed = 1;
|
||||
|
||||
/* Do not copy the forward slash to the root
|
||||
* if it is not a relative path. Instead
|
||||
* move over the slash to the next segment.
|
||||
*/
|
||||
if (relative && (dst == input)) {
|
||||
src++;
|
||||
goto length; /* Skip the copy */
|
||||
}
|
||||
}
|
||||
|
||||
*(dst++) = *(src++);
|
||||
|
||||
length:
|
||||
ldst = (dst - input);
|
||||
}
|
||||
|
||||
*d = '\0';
|
||||
/* Make sure that there is not a trailing slash in the
|
||||
* normalized form if there was not one in the original form.
|
||||
*/
|
||||
if (!trailing && (dst > input) && *(dst - 1) == '/') {
|
||||
ldst--;
|
||||
dst--;
|
||||
}
|
||||
|
||||
return count;
|
||||
/* Always NUL terminate */
|
||||
*dst = '\0';
|
||||
|
||||
return ldst;
|
||||
}
|
||||
|
||||
char *modsec_build(apr_pool_t *mp) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -22,6 +22,13 @@
|
|||
#include <sys/types.h>
|
||||
#include <apr_file_info.h>
|
||||
|
||||
#ifndef APR_WSTICKY
|
||||
/* Add extra flags added to APR in 0.9.5 */
|
||||
#define APR_USETID 0x8000 /**< Set user id */
|
||||
#define APR_GSETID 0x4000 /**< Set group id */
|
||||
#define APR_WSTICKY 0x2000 /**< Sticky bit */
|
||||
#endif
|
||||
|
||||
#include "modsecurity.h"
|
||||
|
||||
int DSOLOCAL normalize_path_inplace(unsigned char *input, int len, int win, int *changed);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -1050,8 +1050,7 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (rc == RULE_MATCH) {
|
||||
else if (rc == RULE_MATCH) {
|
||||
if (msr->rule_was_intercepted) {
|
||||
/* If the transaction was intercepted by this rule we will
|
||||
* go back. Do note that we are relying on the
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -84,7 +84,7 @@ static int msre_op_rx_param_init(msre_rule *rule, char **error_msg) {
|
|||
*error_msg = NULL;
|
||||
|
||||
/* Compile pattern */
|
||||
regex = msc_pregcomp(rule->ruleset->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset);
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
|
@ -143,8 +143,29 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
|||
* and no memory has to be allocated for any backreferences.
|
||||
*/
|
||||
rc = msc_regexec_capture(regex, target, target_length, ovector, 30, &my_error_msg);
|
||||
if (rc < -1) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Regex execution failed: %s", my_error_msg);
|
||||
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
||||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
|
||||
if (s == NULL) return -1;
|
||||
s->name = apr_pstrdup(msr->mp, "MSC_PCRE_LIMITS_EXCEEDED");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrdup(msr->mp, "1");
|
||||
s->value_len = 1;
|
||||
if ((s->name == NULL)||(s->value == NULL)) return -1;
|
||||
apr_table_setn(msr->tx_vars, s->name, (void *)s);
|
||||
|
||||
*error_msg = apr_psprintf(msr->mp,
|
||||
"Rule execution error - "
|
||||
"PCRE limits exceeded (%d): %s",
|
||||
rc, my_error_msg);
|
||||
|
||||
msr_log(msr, 3, "%s.", *error_msg);
|
||||
|
||||
return 0; /* No match. */
|
||||
}
|
||||
else if (rc < -1) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Regex execution failed (%d): %s",
|
||||
rc, my_error_msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -170,6 +191,7 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
|||
if (s == NULL) return -1;
|
||||
|
||||
s->name = apr_psprintf(msr->mp, "%d", i);
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrmemdup(msr->mp,
|
||||
target + ovector[2 * i], ovector[2 * i + 1] - ovector[2 * i]);
|
||||
s->value_len = (ovector[2 * i + 1] - ovector[2 * i]);
|
||||
|
@ -243,7 +265,8 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
|
|||
char buf[HUGE_STRING_LEN + 1];
|
||||
char *fn;
|
||||
char *next;
|
||||
char *ptr;
|
||||
char *start;
|
||||
char *end;
|
||||
const char *rulefile_path;
|
||||
apr_status_t rc;
|
||||
apr_file_t *fd;
|
||||
|
@ -289,7 +312,7 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
|
|||
}
|
||||
|
||||
/* Open file and read */
|
||||
rc = apr_file_open(&fd, fn, APR_READ | APR_FILE_NOCLEANUP, 0, rule->ruleset->mp);
|
||||
rc = apr_file_open(&fd, fn, APR_READ | APR_BUFFERED | APR_FILE_NOCLEANUP, 0, rule->ruleset->mp);
|
||||
if (rc != APR_SUCCESS) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Could not open phrase file \"%s\": %s", fn, apr_strerror(rc, errstr, 1024));
|
||||
return 0;
|
||||
|
@ -309,21 +332,24 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Remove newline */
|
||||
ptr = buf;
|
||||
while(*ptr != '\0') ptr++;
|
||||
if ((ptr > buf) && (*(ptr - 1) == '\n')) *(ptr - 1) = '\0';
|
||||
/* Trim Whitespace */
|
||||
start = buf;
|
||||
while ((apr_isspace(*start) != 0) && (*start != '\0')) start++;
|
||||
end = buf + strlen(buf);
|
||||
if (end > start) end--;
|
||||
while ((end > start) && (apr_isspace(*end) != 0)) end--;
|
||||
if (end > start) {
|
||||
*(++end) = '\0';
|
||||
}
|
||||
|
||||
/* Ignore empty lines and comments */
|
||||
ptr = buf;
|
||||
while((*ptr != '\0') && apr_isspace(*ptr)) ptr++;
|
||||
if ((*ptr == '\0') || (*ptr == '#')) continue;
|
||||
if ((start == end) || (*start == '#')) continue;
|
||||
|
||||
#ifdef DEBUG_CONF
|
||||
fprintf(stderr, "Adding phrase file pattern: \"%s\"\n", buf);
|
||||
#endif
|
||||
|
||||
acmp_add_pattern(p, buf, NULL, NULL, strlen(buf));
|
||||
acmp_add_pattern(p, start, NULL, NULL, (end - start));
|
||||
}
|
||||
fn = next;
|
||||
}
|
||||
|
@ -369,6 +395,7 @@ static int msre_op_pm_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
|||
if (s == NULL) return -1;
|
||||
|
||||
s->name = "0";
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrdup(msr->mp, match);
|
||||
if (s->value == NULL) return -1;
|
||||
s->value_len = strlen(s->value);
|
||||
|
@ -1067,7 +1094,7 @@ static int msre_op_verifyCC_init(msre_rule *rule, char **error_msg) {
|
|||
*error_msg = NULL;
|
||||
|
||||
/* Compile rule->op_param */
|
||||
regex = msc_pregcomp(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset);
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
|
@ -1159,6 +1186,7 @@ static int msre_op_verifyCC_execute(modsec_rec *msr, msre_rule *rule, msre_var *
|
|||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
if (s == NULL) return -1;
|
||||
s->name = apr_psprintf(msr->mp, "%d", i);
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrmemdup(msr->mp, match, length);
|
||||
s->value_len = length;
|
||||
if ((s->name == NULL)||(s->value == NULL)) return -1;
|
||||
|
@ -1796,18 +1824,27 @@ static int msre_op_validateUtf8Encoding_execute(modsec_rec *msr, msre_rule *rule
|
|||
static int msre_op_eq_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
char **error_msg)
|
||||
{
|
||||
msc_string str;
|
||||
int left, right;
|
||||
char *target = NULL;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if ((var->value == NULL)||(rule->op_param == NULL)) {
|
||||
/* NULL values do not match anything. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
str.value = (char *)rule->op_param;
|
||||
str.value_len = strlen(str.value);
|
||||
|
||||
expand_macros(msr, &str, rule, msr->mp);
|
||||
|
||||
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
|
||||
if (target == NULL) return -1;
|
||||
left = atoi(target);
|
||||
right = atoi(rule->op_param);
|
||||
right = atoi(str.value);
|
||||
|
||||
if (left != right) {
|
||||
/* No match. */
|
||||
|
@ -1825,6 +1862,7 @@ static int msre_op_eq_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
char **error_msg)
|
||||
{
|
||||
msc_string str;
|
||||
int left, right;
|
||||
char *target = NULL;
|
||||
|
||||
|
@ -1833,10 +1871,23 @@ static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if ((var->value == NULL)||(rule->op_param == NULL)) {
|
||||
/* NULL values do not match anything. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
str.value = (char *)rule->op_param;
|
||||
str.value_len = strlen(str.value);
|
||||
|
||||
expand_macros(msr, &str, rule, msr->mp);
|
||||
|
||||
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
|
||||
if (target == NULL) return -1;
|
||||
left = atoi(target);
|
||||
right = atoi(rule->op_param);
|
||||
right = atoi(str.value);
|
||||
|
||||
if (left <= right) {
|
||||
/* No match. */
|
||||
|
@ -1854,6 +1905,7 @@ static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
char **error_msg)
|
||||
{
|
||||
msc_string str;
|
||||
int left, right;
|
||||
char *target = NULL;
|
||||
|
||||
|
@ -1862,10 +1914,23 @@ static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if ((var->value == NULL)||(rule->op_param == NULL)) {
|
||||
/* NULL values do not match anything. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
str.value = (char *)rule->op_param;
|
||||
str.value_len = strlen(str.value);
|
||||
|
||||
expand_macros(msr, &str, rule, msr->mp);
|
||||
|
||||
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
|
||||
if (target == NULL) return -1;
|
||||
left = atoi(target);
|
||||
right = atoi(rule->op_param);
|
||||
right = atoi(str.value);
|
||||
|
||||
if (left >= right) {
|
||||
/* No match. */
|
||||
|
@ -1883,6 +1948,7 @@ static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
char **error_msg)
|
||||
{
|
||||
msc_string str;
|
||||
int left, right;
|
||||
char *target = NULL;
|
||||
|
||||
|
@ -1891,10 +1957,23 @@ static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if ((var->value == NULL)||(rule->op_param == NULL)) {
|
||||
/* NULL values do not match anything. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
str.value = (char *)rule->op_param;
|
||||
str.value_len = strlen(str.value);
|
||||
|
||||
expand_macros(msr, &str, rule, msr->mp);
|
||||
|
||||
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
|
||||
if (target == NULL) return -1;
|
||||
left = atoi(target);
|
||||
right = atoi(rule->op_param);
|
||||
right = atoi(str.value);
|
||||
|
||||
if (left < right) {
|
||||
/* No match. */
|
||||
|
@ -1912,6 +1991,7 @@ static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
char **error_msg)
|
||||
{
|
||||
msc_string str;
|
||||
int left, right;
|
||||
char *target = NULL;
|
||||
|
||||
|
@ -1920,10 +2000,23 @@ static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
if ((var->value == NULL)||(rule->op_param == NULL)) {
|
||||
/* NULL values do not match anything. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
str.value = (char *)rule->op_param;
|
||||
str.value_len = strlen(str.value);
|
||||
|
||||
expand_macros(msr, &str, rule, msr->mp);
|
||||
|
||||
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
|
||||
if (target == NULL) return -1;
|
||||
left = atoi(target);
|
||||
right = atoi(rule->op_param);
|
||||
right = atoi(str.value);
|
||||
|
||||
if (left > right) {
|
||||
/* No match. */
|
||||
|
@ -1936,7 +2029,7 @@ static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
@ -1379,6 +1379,30 @@ static int var_multipart_invalid_quoting_generate(modsec_rec *msr, msre_var *var
|
|||
}
|
||||
}
|
||||
|
||||
/* MULTIPART_INVALID_HEADER_FOLDING */
|
||||
|
||||
static int var_multipart_invalid_header_folding_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_invalid_header_folding != 0)) {
|
||||
return var_simple_generate(var, vartab, mptmp, "1");
|
||||
} else {
|
||||
return var_simple_generate(var, vartab, mptmp, "0");
|
||||
}
|
||||
}
|
||||
|
||||
/* MULTIPART_FILE_LIMIT_EXCEEDED */
|
||||
|
||||
static int var_multipart_file_limit_exceeded_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_file_limit_exceeded != 0)) {
|
||||
return var_simple_generate(var, vartab, mptmp, "1");
|
||||
} else {
|
||||
return var_simple_generate(var, vartab, mptmp, "0");
|
||||
}
|
||||
}
|
||||
|
||||
/* MULTIPART_STRICT_ERROR */
|
||||
|
||||
static int var_multipart_strict_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
|
@ -1395,6 +1419,8 @@ static int var_multipart_strict_error_generate(modsec_rec *msr, msre_var *var, m
|
|||
||(msr->mpd->flag_lf_line != 0)
|
||||
||(msr->mpd->flag_missing_semicolon != 0)
|
||||
||(msr->mpd->flag_invalid_quoting != 0)
|
||||
||(msr->mpd->flag_invalid_header_folding != 0)
|
||||
||(msr->mpd->flag_file_limit_exceeded != 0)
|
||||
) {
|
||||
return var_simple_generate(var, vartab, mptmp, "1");
|
||||
}
|
||||
|
@ -2643,6 +2669,28 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
|||
PHASE_REQUEST_BODY
|
||||
);
|
||||
|
||||
/* MULTIPART_INVALID_HEADER_FOLDING */
|
||||
msre_engine_variable_register(engine,
|
||||
"MULTIPART_INVALID_HEADER_FOLDING",
|
||||
VAR_SIMPLE,
|
||||
0, 0,
|
||||
NULL,
|
||||
var_multipart_invalid_header_folding_generate,
|
||||
VAR_DONT_CACHE, /* flag */
|
||||
PHASE_REQUEST_BODY
|
||||
);
|
||||
|
||||
/* MULTIPART_FILE_LIMIT_EXCEEDED */
|
||||
msre_engine_variable_register(engine,
|
||||
"MULTIPART_FILE_LIMIT_EXCEEDED",
|
||||
VAR_SIMPLE,
|
||||
0, 0,
|
||||
NULL,
|
||||
var_multipart_file_limit_exceeded_generate,
|
||||
VAR_DONT_CACHE, /* flag */
|
||||
PHASE_REQUEST_BODY
|
||||
);
|
||||
|
||||
/* MULTIPART_STRICT_ERROR */
|
||||
msre_engine_variable_register(engine,
|
||||
"MULTIPART_STRICT_ERROR",
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
### Logging tests
|
||||
|
||||
# log/nolog
|
||||
# log/nolog (pass)
|
||||
{
|
||||
type => "action",
|
||||
comment => "log",
|
||||
comment => "log (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,log"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
|
@ -22,9 +26,12 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "nolog",
|
||||
comment => "nolog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,nolog"
|
||||
|
@ -41,19 +48,70 @@
|
|||
),
|
||||
},
|
||||
|
||||
# auditlog/noauditlog
|
||||
# log/nolog (deny)
|
||||
{
|
||||
type => "action",
|
||||
comment => "auditlog",
|
||||
comment => "log (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,log"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "nolog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,nolog"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
|
||||
# auditlog/noauditlog (pass)
|
||||
{
|
||||
type => "action",
|
||||
comment => "auditlog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,auditlog"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
|
@ -64,15 +122,18 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "noauditlog",
|
||||
comment => "noauditlog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,noauditlog"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
|
@ -83,19 +144,70 @@
|
|||
),
|
||||
},
|
||||
|
||||
# All log/nolog auditlog/noauditlog combos
|
||||
# auditlog/noauditlog (deny)
|
||||
{
|
||||
type => "action",
|
||||
comment => "log,auditlog",
|
||||
comment => "auditlog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,auditlog"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "noauditlog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,noauditlog"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
|
||||
# All log/nolog auditlog/noauditlog combos (pass)
|
||||
{
|
||||
type => "action",
|
||||
comment => "log,auditlog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,log,auditlog"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
|
@ -106,15 +218,18 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "log,noauditlog",
|
||||
comment => "log,noauditlog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,log,noauditlog"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
|
@ -126,9 +241,12 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "nolog,auditlog",
|
||||
comment => "nolog,auditlog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,nolog,auditlog"
|
||||
|
@ -145,9 +263,12 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "nolog,noauditlog",
|
||||
comment => "nolog,noauditlog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,nolog,noauditlog"
|
||||
|
@ -165,16 +286,19 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "auditlog,log",
|
||||
comment => "auditlog,log (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,auditlog,log"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
|
@ -185,9 +309,12 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "auditlog,nolog",
|
||||
comment => "auditlog,nolog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,auditlog,nolog"
|
||||
|
@ -205,15 +332,18 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "noauditlog,log",
|
||||
comment => "noauditlog,log (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,noauditlog,log"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
|
||||
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
|
@ -225,9 +355,12 @@
|
|||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "noauditlog,nolog",
|
||||
comment => "noauditlog,nolog (pass)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,pass,noauditlog,nolog"
|
||||
|
@ -244,3 +377,188 @@
|
|||
),
|
||||
},
|
||||
|
||||
# All log/nolog auditlog/noauditlog combos (deny)
|
||||
{
|
||||
type => "action",
|
||||
comment => "log,auditlog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,log,auditlog"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "log,noauditlog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,log,noauditlog"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "nolog,auditlog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,nolog,auditlog"
|
||||
),
|
||||
match_log => {
|
||||
audit => [ qr/-H--\s+Message: .*Stopwatch: /s, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "nolog,noauditlog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,nolog,noauditlog"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "auditlog,log (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,auditlog,log"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "auditlog,nolog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,auditlog,nolog"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "noauditlog,log (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,noauditlog,log"
|
||||
),
|
||||
match_log => {
|
||||
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
{
|
||||
type => "action",
|
||||
comment => "noauditlog,nolog (deny)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog "$ENV{DEBUG_LOG}"
|
||||
SecDebugLogLevel 9
|
||||
SecAuditLogRelevantStatus xxx
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLog "$ENV{AUDIT_LOG}"
|
||||
SecAction "phase:1,deny,status:403,noauditlog,nolog"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/ModSecurity: /, 1 ],
|
||||
-audit => [ qr/./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^403$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||
),
|
||||
},
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
return 1;
|
||||
},
|
||||
match_log => {
|
||||
debug => [ qr/Created temporary file: $ENV{TEMP_DIR}/, 1 ],
|
||||
debug => [ qr/Created temporary file.*$ENV{TEMP_DIR}/, 1 ],
|
||||
-debug => [ qr/Failed to /, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -27,64 +27,190 @@
|
|||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "/foo/bar//baz",
|
||||
output => "/foo/bar/baz",
|
||||
input => "x",
|
||||
output => "x",
|
||||
ret => 0,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => ".",
|
||||
output => "",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "/foo/bar baz/././././boo//eek/././../whoa",
|
||||
output => "/foo/bar baz/boo/whoa",
|
||||
input => "./",
|
||||
output => "",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "./foo/bar baz/././././boo//eek/././../whoa",
|
||||
output => "./foo/bar baz/boo/whoa",
|
||||
input => "./..",
|
||||
output => "..",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "/./foo/bar baz/././././boo//eek/././../whoa",
|
||||
output => "/foo/bar baz/boo/whoa",
|
||||
input => "./../",
|
||||
output => "../",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "//foo/bar baz/././././boo//eek/././../whoa",
|
||||
output => "/foo/bar baz/boo/whoa",
|
||||
input => "..",
|
||||
output => "..",
|
||||
ret => 0,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "../",
|
||||
output => "../",
|
||||
ret => 0,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "../.",
|
||||
output => "..",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "//foo/bar baz/././././boo//eek/././../whoa/./",
|
||||
output => "/foo/bar baz/boo/whoa/",
|
||||
input => ".././",
|
||||
output => "../",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "/./foo/bar baz/././././boo//eek/././../whoa//",
|
||||
output => "/foo/bar baz/boo/whoa/",
|
||||
input => "../..",
|
||||
output => "../..",
|
||||
ret => 0,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "../../",
|
||||
output => "../../",
|
||||
ret => 0,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "/dir/foo//bar",
|
||||
output => "/dir/foo/bar",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "/./../../../../../../../../etc/passwd",
|
||||
output => "/etc/passwd",
|
||||
input => "dir/foo//bar/",
|
||||
output => "dir/foo/bar/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "/./.././../../../../../../../etc/../etc/./passwd",
|
||||
output => "/etc/passwd",
|
||||
input => "dir/../foo",
|
||||
output => "foo",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/../../foo",
|
||||
output => "../foo",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/./.././../../foo/bar",
|
||||
output => "../../foo/bar",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/./.././../../foo/bar/.",
|
||||
output => "../../foo/bar",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/./.././../../foo/bar/./",
|
||||
output => "../../foo/bar/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/./.././../../foo/bar/..",
|
||||
output => "../../foo",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/./.././../../foo/bar/../",
|
||||
output => "../../foo/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/./.././../../foo/bar/",
|
||||
output => "../../foo/bar/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir//.//..//.//..//..//foo//bar",
|
||||
output => "../../foo/bar",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir//.//..//.//..//..//foo//bar//",
|
||||
output => "../../foo/bar/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/subdir/subsubdir/subsubsubdir/../../..",
|
||||
output => "dir",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/./subdir/./subsubdir/./subsubsubdir/../../..",
|
||||
output => "dir",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "dir/./subdir/../subsubdir/../subsubsubdir/..",
|
||||
output => "dir",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePath",
|
||||
input => "/dir/./subdir/../subsubdir/../subsubsubdir/../",
|
||||
output => "/dir/",
|
||||
ret => 1,
|
||||
},
|
||||
|
||||
|
|
|
@ -27,64 +27,190 @@
|
|||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\foo\\bar\\\\baz",
|
||||
output => "/foo/bar/baz",
|
||||
input => "x",
|
||||
output => "x",
|
||||
ret => 0,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => ".",
|
||||
output => "",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
|
||||
output => "/foo/bar baz/boo/whoa",
|
||||
input => ".\\",
|
||||
output => "",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => ".\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
|
||||
output => "./foo/bar baz/boo/whoa",
|
||||
input => ".\\..",
|
||||
output => "..",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\.\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
|
||||
output => "/foo/bar baz/boo/whoa",
|
||||
input => ".\\..\\",
|
||||
output => "../",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
|
||||
output => "/foo/bar baz/boo/whoa",
|
||||
input => "..",
|
||||
output => "..",
|
||||
ret => 0,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "..\\",
|
||||
output => "../",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa\\.\\",
|
||||
output => "/foo/bar baz/boo/whoa/",
|
||||
input => "..\\.",
|
||||
output => "..",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\.\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa\\\\",
|
||||
output => "/foo/bar baz/boo/whoa/",
|
||||
input => "..\\.\\",
|
||||
output => "../",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\.\\..\\..\\..\\..\\..\\..\\..\\..\\etc\\passwd",
|
||||
output => "/etc/passwd",
|
||||
input => "..\\..",
|
||||
output => "../..",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\.\\..\\.\\..\\..\\..\\..\\..\\..\\..\\etc\\..\\etc\\.\\passwd",
|
||||
output => "/etc/passwd",
|
||||
input => "..\\..\\",
|
||||
output => "../../",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\dir\\foo\\\\bar",
|
||||
output => "/dir/foo/bar",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\foo\\\\bar\\",
|
||||
output => "dir/foo/bar/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\..\\foo",
|
||||
output => "foo",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\..\\..\\foo",
|
||||
output => "../foo",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\.\\..\\.\\..\\..\\foo\\bar",
|
||||
output => "../../foo/bar",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\.",
|
||||
output => "../../foo/bar",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\.\\",
|
||||
output => "../../foo/bar/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\..",
|
||||
output => "../../foo",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\..\\",
|
||||
output => "../../foo/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\",
|
||||
output => "../../foo/bar/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\\\.\\\\..\\\\.\\\\..\\\\..\\\\foo\\\\bar",
|
||||
output => "../../foo/bar",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\\\.\\\\..\\\\.\\\\..\\\\..\\\\foo\\\\bar\\\\",
|
||||
output => "../../foo/bar/",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\subdir\\subsubdir\\subsubsubdir\\..\\..\\..",
|
||||
output => "dir",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\.\\subdir\\.\\subsubdir\\.\\subsubsubdir\\..\\..\\..",
|
||||
output => "dir",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "dir\\.\\subdir\\..\\subsubdir\\..\\subsubsubdir\\..",
|
||||
output => "dir",
|
||||
ret => 1,
|
||||
},
|
||||
{
|
||||
type => "tfn",
|
||||
name => "normalisePathWin",
|
||||
input => "\\dir\\.\\subdir\\..\\subsubdir\\..\\subsubsubdir\\..\\",
|
||||
output => "/dir/",
|
||||
ret => 1,
|
||||
},
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
|
||||
* Copyright (c) 2004-2010 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</xsl:template>
|
||||
|
||||
<xsl:template name="user.footer.navigation">
|
||||
<div class="copyright" align="center">Copyright (C) 2004-2009 <a href="http://www.breach.com">Breach Security</a></div>
|
||||
<div class="copyright" align="center">Copyright (C) 2004-2010 <a href="http://www.breach.com">Breach Security</a></div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="article.titlepage.separator">
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</xsl:template>
|
||||
|
||||
<xsl:template name="user.footer.navigation">
|
||||
<div class="copyright" align="center">Copyright (C) 2004-2009 <a href="http://www.breach.com">Breach Security</a></div>
|
||||
<div class="copyright" align="center">Copyright (C) 2004-2010 <a href="http://www.breach.com">Breach Security</a></div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="article.titlepage.separator">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<releaseinfo>Version 1.0 / (April 10, 2007)</releaseinfo>
|
||||
|
||||
<copyright>
|
||||
<year>2004-2009</year>
|
||||
<year>2004-2010</year>
|
||||
|
||||
<holder>Breach Security, Inc. (<ulink
|
||||
url="http://www.breach.com">http://www.breach.com</ulink>)</holder>
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
<article>
|
||||
<title><trademark class="registered">ModSecurity</trademark> Reference Manual</title>
|
||||
<articleinfo>
|
||||
<releaseinfo>Version 2.6.0-trunk (Nov 12, 2009)</releaseinfo>
|
||||
<releaseinfo>Version 2.6.0-trunk (Feb 3, 2009)</releaseinfo>
|
||||
<copyright>
|
||||
<year>2004-2009</year>
|
||||
<year>2004-2010</year>
|
||||
<holder>Breach Security, Inc. (<ulink url="http://www.breach.com"
|
||||
>http://www.breach.com</ulink>)</holder>
|
||||
</copyright>
|
||||
|
@ -218,10 +218,11 @@
|
|||
central repository, then you will also need the curl library.</para>
|
||||
<para><ulink type="" url="http://curl.haxx.se/libcurl/"
|
||||
>http://curl.haxx.se/libcurl/</ulink></para>
|
||||
|
||||
<note>
|
||||
<para>Many have had issues with libcurl linked with the GnuTLS library for SSL/TLS
|
||||
support. It is recommended that the openssl library be used for SSL/TLS support in
|
||||
libcurl.</para>
|
||||
<para>Many have had issues with libcurl linked with the GnuTLS
|
||||
library for SSL/TLS support. It is recommended that the openssl
|
||||
library be used for SSL/TLS support in libcurl.</para>
|
||||
</note>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
@ -999,6 +1000,61 @@ SecRule &REQUEST_HEADERS:Accept "@eq 0" \
|
|||
SecMarker 99</emphasis></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>SecPcreMatchLimit</literal></title>
|
||||
|
||||
<para><emphasis>Description:</emphasis>Sets the the match limit in the
|
||||
PCRE library. See the pcre_extra field in the pcreapi man page.</para>
|
||||
|
||||
<para><emphasis>Syntax:</emphasis> <literal
|
||||
moreinfo="none">SecPcreMatchLimit value</literal></para>
|
||||
|
||||
<para><emphasis>Example Usage:</emphasis> <literal
|
||||
moreinfo="none">SecPcreMatchLimit 1500</literal></para>
|
||||
|
||||
<para><emphasis>Processing Phase:</emphasis> N/A</para>
|
||||
|
||||
<para><emphasis>Scope:</emphasis> Global</para>
|
||||
|
||||
<para><emphasis>Version:</emphasis> 2.5.12</para>
|
||||
|
||||
<para><emphasis>Dependencies/Notes:</emphasis> Default is set at compile
|
||||
(1500 by default)</para>
|
||||
|
||||
<para>The <literal>--enable-pcre-match-limit=val</literal> configure
|
||||
option will set a custom default and the
|
||||
<literal>--disable-pcre-match-limit</literal> option will resort to the
|
||||
compiled PCRE library default.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>SecPcreMatchLimitRecursion</literal></title>
|
||||
|
||||
<para><emphasis>Description:</emphasis>Sets the the match limit
|
||||
recursion in the PCRE library. See the pcre_extra field in the pcreapi
|
||||
man page.</para>
|
||||
|
||||
<para><emphasis>Syntax:</emphasis> <literal
|
||||
moreinfo="none">SecPcreMatchLimitRecursion value</literal></para>
|
||||
|
||||
<para><emphasis>Example Usage:</emphasis> <literal
|
||||
moreinfo="none">SecPcreMatchLimitRecursion 1500</literal></para>
|
||||
|
||||
<para><emphasis>Processing Phase:</emphasis> N/A</para>
|
||||
|
||||
<para><emphasis>Scope:</emphasis> Global</para>
|
||||
|
||||
<para><emphasis>Version:</emphasis> 2.5.12</para>
|
||||
|
||||
<para><emphasis>Dependencies/Notes:</emphasis> Default is set at compile
|
||||
(1500 by default)</para>
|
||||
|
||||
<para>The <literal>--enable-pcre-match-limit-recursion=val</literal>
|
||||
configure option will set a custom default and the
|
||||
<literal>--disable-pcre-match-limit-recursion</literal> option will
|
||||
resort to the compiled PCRE library default.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>SecPdfProtect</literal></title>
|
||||
<para><emphasis>Description:</emphasis> Enables the PDF XSS protection functionality. Once
|
||||
|
@ -1670,6 +1726,42 @@ SecRuleUpdateActionById 12345 "t:compressWhitespace,deny,status:403,msg:'A new m
|
|||
as the temporary directory defined with <literal moreinfo="none">SecTmpDir</literal>. This
|
||||
directive is used with <literal>SecUploadKeepFiles</literal>.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>SecUploadFileLimit</literal></title>
|
||||
|
||||
<para><emphasis>Description:</emphasis> Configures the maximum number of
|
||||
file uploads processed in a multipart POST.</para>
|
||||
|
||||
<para><emphasis>Syntax:</emphasis> <literal
|
||||
moreinfo="none">SecUploadFileLimit number</literal></para>
|
||||
|
||||
<para><emphasis>Example Usage:</emphasis> <literal
|
||||
moreinfo="none">SecUploadFileLimit 10</literal></para>
|
||||
|
||||
<para><emphasis>Processing Phase:</emphasis> N/A</para>
|
||||
|
||||
<para><emphasis>Scope:</emphasis> Any</para>
|
||||
|
||||
<para><emphasis>Version:</emphasis> 2.5.12</para>
|
||||
|
||||
<para><emphasis>Dependencies/Notes:</emphasis> The default is set to 100
|
||||
files, but you are encouraged to reduce this value. Any file over the
|
||||
limit will not be extracted and the <literal
|
||||
moreinfo="none">MULTIPART_FILE_LIMIT_EXCEEDED</literal> and <literal
|
||||
moreinfo="none">MULTIPART_STRICT_ERROR</literal> flags will be set. To
|
||||
prevent bypassing any file checks, you must check for one of these
|
||||
flags.</para>
|
||||
|
||||
<note>
|
||||
<para>If the limit is exceeded, the part name and file name will still
|
||||
be recorded in <literal moreinfo="none">FILES_NAME</literal> and
|
||||
<literal moreinfo="none">FILES</literal>, the file size will be
|
||||
recorded in <literal moreinfo="none">FILES_SIZES</literal>, but there
|
||||
will be no record in <literal moreinfo="none">FILES_TMPNAMES</literal>
|
||||
as a temporary file was not created.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title><literal>SecUploadFileMode</literal></title>
|
||||
<para><emphasis>Description:</emphasis> Configures the mode (permissions) of any uploaded
|
||||
|
@ -2111,19 +2203,30 @@ SecRule ARGS "@pm some key words" id:12345,deny,status:500</programlisting>
|
|||
</section>
|
||||
<section>
|
||||
<title><literal>MULTIPART_STRICT_ERROR</literal></title>
|
||||
<para><literal>MULTIPART_STRICT_ERROR</literal> will be set to <literal>1</literal> when any
|
||||
of the following variables is also set to <literal>1</literal>: <literal
|
||||
>REQBODY_PROCESSOR_ERROR</literal>, <literal>MULTIPART_BOUNDARY_QUOTED</literal>, <literal
|
||||
>MULTIPART_BOUNDARY_WHITESPACE</literal>, <literal>MULTIPART_DATA_BEFORE</literal>,
|
||||
<literal>MULTIPART_DATA_AFTER</literal>, <literal>MULTIPART_HEADER_FOLDING</literal>,
|
||||
<literal>MULTIPART_LF_LINE</literal>, <literal>MULTIPART_SEMICOLON_MISSING</literal>
|
||||
<literal>MULTIPART_INVALID_QUOTING</literal>. Each of these variables covers one unusual
|
||||
(although sometimes legal) aspect of the request body in <literal>multipart/form-data
|
||||
format</literal>. Your policies should <emphasis>always</emphasis> contain a rule to check
|
||||
either this variable (easier) or one or more individual variables (if you know exactly what
|
||||
you want to accomplish). Depending on the rate of false positives and your default policy
|
||||
you should decide whether to block or just warn when the rule is triggered.</para>
|
||||
<para>The best way to use this variable is as in the example below:</para>
|
||||
<para><literal>MULTIPART_STRICT_ERROR</literal> will be set to
|
||||
<literal>1</literal> when any of the following variables is also set to
|
||||
<literal>1</literal>: <literal>REQBODY_PROCESSOR_ERROR</literal>,
|
||||
<literal>MULTIPART_BOUNDARY_QUOTED</literal>,
|
||||
<literal>MULTIPART_BOUNDARY_WHITESPACE</literal>,
|
||||
<literal>MULTIPART_DATA_BEFORE</literal>,
|
||||
<literal>MULTIPART_DATA_AFTER</literal>,
|
||||
<literal>MULTIPART_HEADER_FOLDING</literal>,
|
||||
<literal>MULTIPART_LF_LINE</literal>,
|
||||
<literal>MULTIPART_SEMICOLON_MISSING</literal>
|
||||
<literal>MULTIPART_INVALID_QUOTING</literal>
|
||||
<literal>MULTIPART_INVALID_HEADER_FOLDING</literal>
|
||||
<literal>MULTIPART_FILE_LIMIT_EXCEEDED</literal>. Each of these
|
||||
variables covers one unusual (although sometimes legal) aspect of the
|
||||
request body in <literal>multipart/form-data format</literal>. Your
|
||||
policies should <emphasis>always</emphasis> contain a rule to check
|
||||
either this variable (easier) or one or more individual variables (if
|
||||
you know exactly what you want to accomplish). Depending on the rate of
|
||||
false positives and your default policy you should decide whether to
|
||||
block or just warn when the rule is triggered.</para>
|
||||
|
||||
<para>The best way to use this variable is as in the example
|
||||
below:</para>
|
||||
|
||||
<programlisting>SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
|
||||
"phase:2,t:none,log,deny,msg:'Multipart request body \
|
||||
failed strict validation: \
|
||||
|
@ -2135,7 +2238,9 @@ DA %{MULTIPART_DATA_AFTER}, \
|
|||
HF %{MULTIPART_HEADER_FOLDING}, \
|
||||
LF %{MULTIPART_LF_LINE}, \
|
||||
SM %{MULTIPART_SEMICOLON_MISSING}, \
|
||||
IQ %{MULTIPART_INVALID_QUOTING}'"</programlisting>
|
||||
IQ %{MULTIPART_INVALID_QUOTING}, \
|
||||
IQ %{MULTIPART_INVALID_HEADER_FOLDING}, \
|
||||
FE %{MULTIPART_FILE_LIMIT_EXCEEDED}'"</programlisting>
|
||||
<para>The <literal>multipart/form-data</literal> parser was upgraded in ModSecurity v2.1.3 to
|
||||
actively look for signs of evasion. Many variables (as listed above) were added to expose
|
||||
various facts discovered during the parsing process. The <literal
|
||||
|
@ -2570,6 +2675,21 @@ SecAction setsid:%{REQUEST_COOKIES.PHPSESSID}</programlisting>
|
|||
using the <literal moreinfo="none">@rx</literal> operator with capturing parens and the
|
||||
<literal moreinfo="none">capture</literal> action.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal moreinfo="none">TX:MSC_.*</literal> - ModSecurity
|
||||
processing flags.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal
|
||||
moreinfo="none">MSC_PCRE_LIMITS_EXCEEDED</literal> - Set
|
||||
non-zero if PCRE match limits are exceeded. See <literal
|
||||
moreinfo="none">SecPcreMatchLimit</literal> and <literal
|
||||
moreinfo="none">SecPcreMatchLimitRecursion</literal>.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<programlisting format="linespecific">SecRule WEBSERVER_ERROR_LOG "does not exist" "phase:5,pass,<emphasis>setvar:tx.score=+5</emphasis>"
|
||||
SecRule<emphasis> TX:SCORE</emphasis> "@gt 20" deny,log</programlisting>
|
||||
|
@ -3256,7 +3376,7 @@ setvar:session.suspicious=1,<emphasis>expirevar:session.suspicious=3600</emphasi
|
|||
<para>430,000-699,999; unused (available for reservation).</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>700,000-799,999; reserved for Ivan Ristic.</para>
|
||||
<para>700,000-799,999; reserved for Ivan Ristic.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
@ -3731,6 +3851,9 @@ SecRule ARGS:route "!<emphasis>@endsWith %{REQUEST_ADDR}</emphasis>" t:none,deny
|
|||
"equal to."</para>
|
||||
<para>Example:</para>
|
||||
<programlisting format="linespecific">SecRule &REQUEST_HEADERS_NAMES "<emphasis>@eq</emphasis> 15"</programlisting>
|
||||
|
||||
<para>Macro expansion is performed so you may use variable names such as
|
||||
<literal>%{TX.1}</literal>, etc.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>ge</literal></title>
|
||||
|
@ -3738,6 +3861,9 @@ SecRule ARGS:route "!<emphasis>@endsWith %{REQUEST_ADDR}</emphasis>" t:none,deny
|
|||
"greater than or equal to."</para>
|
||||
<para>Example:</para>
|
||||
<programlisting format="linespecific">SecRule &REQUEST_HEADERS_NAMES "<emphasis>@ge</emphasis> 15"</programlisting>
|
||||
|
||||
<para>Macro expansion is performed so you may use variable names such as
|
||||
<literal>%{TX.1}</literal>, etc.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>geoLookup</literal></title>
|
||||
|
@ -3766,6 +3892,9 @@ SecRule &GEO "@eq 0" "deny,status:403,msg:'Failed to lookup IP'"</programlis
|
|||
"greater than."</para>
|
||||
<para>Example:</para>
|
||||
<programlisting format="linespecific">SecRule &REQUEST_HEADERS_NAMES "<emphasis>@gt</emphasis> 15"</programlisting>
|
||||
|
||||
<para>Macro expansion is performed so you may use variable names such as
|
||||
<literal>%{TX.1}</literal>, etc.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>inspectFile</literal></title>
|
||||
|
@ -3800,6 +3929,9 @@ end</programlisting>
|
|||
"less than or equal to."</para>
|
||||
<para>Example:</para>
|
||||
<programlisting format="linespecific">SecRule &REQUEST_HEADERS_NAMES "<emphasis>@le</emphasis> 15"</programlisting>
|
||||
|
||||
<para>Macro expansion is performed so you may use variable names such as
|
||||
<literal>%{TX.1}</literal>, etc.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>lt</literal></title>
|
||||
|
@ -3807,6 +3939,9 @@ end</programlisting>
|
|||
"less than."</para>
|
||||
<para>Example:</para>
|
||||
<programlisting format="linespecific">SecRule &REQUEST_HEADERS_NAMES "<emphasis>@lt</emphasis> 15"</programlisting>
|
||||
|
||||
<para>Macro expansion is performed so you may use variable names such as
|
||||
<literal>%{TX.1}</literal>, etc.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>pm</literal></title>
|
||||
|
@ -3827,15 +3962,34 @@ end</programlisting>
|
|||
<para>Notes:</para>
|
||||
<orderedlist continuation="restarts" inheritnum="ignore">
|
||||
<listitem>
|
||||
<para>The contents of the files should be one phrase per line. End of line markers will be
|
||||
stripped from the phrases, however, whitespace will not be trimmed from phrases in the
|
||||
file. Empty lines and comment lines (beginning with a '#') are ignored.</para>
|
||||
<para>The contents of the files should be one phrase per line. End
|
||||
of line markers will be stripped from the phrases (LF and CRLF), and
|
||||
whitespace is trimmed from both sides of the phrases. Empty lines
|
||||
and comment lines (beginning with a '#') are ignored.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>To allow easier inclusion of phrase files with rulesets, relative paths may be used
|
||||
to the phrase files. In this case, the path of the file containing the rule is prepended
|
||||
to the phrase file path.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>To allow easier matching of whole IP addresses, you can add
|
||||
boundary characters to the phrases. For example, use "/1.2.3.4/"
|
||||
instead of "1.2.3.4". You can then insert these characters into the
|
||||
target prior to a match:</para>
|
||||
|
||||
<programlisting format="linespecific">SecAction "phase:1,pass,nolog,setvar:tx.remote_addr=/%{REMOTE_ADDR}/"
|
||||
SecRule TX:REMOTE_ADDR "<emphasis>@pmFromFile ip-blacklist.txt</emphasis>" "deny,status:403
|
||||
|
||||
# ip-blacklist.txt contents:
|
||||
# NOTE: All IPs must be prefixed/suffixed with "/" as the rules
|
||||
# will add in this character as a boundary to ensure
|
||||
# the entire IP is matched.
|
||||
# SecAction "phase:1,pass,nolog,setvar:tx.remote_addr='/%{REMOTE_ADDR}/'"
|
||||
/1.2.3.4/
|
||||
/5.6.7.8/</programlisting>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>Example:</para>
|
||||
<programlisting format="linespecific">SecRule REQUEST_HEADERS:User-Agent "<emphasis>@pm</emphasis> /path/to/blacklist1 blacklist2" "deny,status:403</programlisting>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<articleinfo>
|
||||
<releaseinfo>2.6.0-trunk (April 22, 2009)</releaseinfo>
|
||||
<copyright>
|
||||
<year>2004-2009</year>
|
||||
<year>2004-2010</year>
|
||||
<holder>Breach Security, Inc. (<ulink url="http://www.breach.com"
|
||||
>http://www.breach.com</ulink>)</holder>
|
||||
</copyright>
|
||||
|
|
|
@ -4,10 +4,15 @@ SecRuleEngine On
|
|||
SecRequestBodyAccess On
|
||||
SecResponseBodyAccess Off
|
||||
|
||||
# PCRE Tuning
|
||||
SecPcreMatchLimit 1000
|
||||
SecPcreMatchLimitRecursion 1000
|
||||
|
||||
# Handling of file uploads
|
||||
# TODO Choose a folder private to Apache.
|
||||
# SecUploadDir /opt/apache-frontend/tmp/
|
||||
SecUploadKeepFiles Off
|
||||
SecUploadFileLimit 10
|
||||
|
||||
# Debug log
|
||||
SecDebugLog logs/modsec_debug.log
|
||||
|
@ -53,8 +58,19 @@ DA %{MULTIPART_DATA_AFTER}, \
|
|||
HF %{MULTIPART_HEADER_FOLDING}, \
|
||||
LF %{MULTIPART_LF_LINE}, \
|
||||
SM %{MULTIPART_SEMICOLON_MISSING}, \
|
||||
IQ %{MULTIPART_INVALID_QUOTING}'"
|
||||
IQ %{MULTIPART_INVALID_QUOTING}, \
|
||||
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
|
||||
IH %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
|
||||
|
||||
# Did we see anything that might be a boundary?
|
||||
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
|
||||
"phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
|
||||
|
||||
# Some internal errors will set flags in TX and we will need to look for these.
|
||||
# All of these are prefixed with "MSC_". The following flags currently exist:
|
||||
#
|
||||
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
|
||||
#
|
||||
SecRule TX:/^MSC_/ "!@streq 0" \
|
||||
"phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче