mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Adds support to suspicious and whitelist to Read and Write limits
The operators @ipMatch, @ipMatchF and @ipMatchFromFile were added to the functions: SecReadStateLimit and SecReadStateLimit, by using them it is possible to declare a suspicious list. When a suspicious list is given, the {Read|Write}StateLimit will be applied just to the IPs that belongs to that restricted list. Note that the negative of those operators (e.g. !@ipMatch) can be used to place a whitelist. The {Read|Write}StateLimit restrictions will not be applied to those in the whitelist. This current version the Sec{Read|Write}StateLimit can be used varios times to add elements to both lists, however, the last informed limit will be applied for the entire group. This feature is experimental, and suggestions on how to improve it are very welcome. For further discussion use the issue: #353.
This commit is contained in:
@@ -1670,18 +1670,79 @@ static const char *cmd_rule_perf_time(cmd_parms *cmd, void *_dcfg,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *parser_conn_limits_operator(apr_pool_t *mp, const char *p2,
|
||||
TreeRoot **whitelist, msre_ipmatch **whitelist_param,
|
||||
TreeRoot **suspicious_list, msre_ipmatch **suspicious_list_param,
|
||||
const char *filename)
|
||||
{
|
||||
int res = 0;
|
||||
char *config_orig_path;
|
||||
char *param = strchr(p2, ' ');
|
||||
char *file = NULL;
|
||||
char *error_msg = NULL;
|
||||
param++;
|
||||
|
||||
config_orig_path = apr_pstrndup(mp, filename,
|
||||
strlen(filename) - strlen(apr_filepath_name_get(filename)));
|
||||
|
||||
apr_filepath_merge(&file, config_orig_path, param, APR_FILEPATH_TRUENAME,
|
||||
mp);
|
||||
|
||||
if ((strncasecmp(p2, "!@ipMatchFromFile", strlen("!@ipMatchFromFile")) == 0) ||
|
||||
(strncasecmp(p2, "!@ipMatchF", strlen("!@ipMatchF")) == 0)) {
|
||||
|
||||
res = ip_tree_from_file(whitelist,
|
||||
file, mp, NULL);
|
||||
}
|
||||
else if (strncasecmp(p2, "!@ipMatch", strlen("!@ipMatch")) == 0) {
|
||||
res = ip_list_from_param(mp, param,
|
||||
whitelist_param, &error_msg);
|
||||
}
|
||||
else if ((strncasecmp(p2, "@ipMatchFromFile", strlen("@ipMatchFromFile")) == 0) ||
|
||||
(strncasecmp(p2, "@ipMatchF", strlen("@ipMatchF")) == 0)) {
|
||||
|
||||
res = ip_tree_from_file(suspicious_list,
|
||||
file, mp, NULL);
|
||||
}
|
||||
else if (strncasecmp(p2, "@ipMatch", strlen("@ipMatch")) == 0) {
|
||||
res = ip_list_from_param(mp, param,
|
||||
suspicious_list_param, &error_msg);
|
||||
}
|
||||
else {
|
||||
return apr_psprintf(mp, "ModSecurity: Invalid operator for " \
|
||||
"SecReadStateLimit: %s, expected operators: @ipMatch, @ipMatchF " \
|
||||
"or @ipMatchFromFile with or without !", p2);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
char *error;
|
||||
error = apr_psprintf(mp, "ModSecurity: failed to load IPs " \
|
||||
"from: %s", param);
|
||||
|
||||
if (*error_msg) {
|
||||
error = apr_psprintf(mp, "%s %s", error, error_msg);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Add SecReadStateLimit configuration option
|
||||
*
|
||||
* \param cmd Pointer to configuration data
|
||||
* \param _dcfg Pointer to directory configuration
|
||||
* \param p1 Pointer to configuration option
|
||||
* \param p2 Pointer to configuration option
|
||||
*
|
||||
* \retval NULL On failure
|
||||
* \retval apr_psprintf On Success
|
||||
*/
|
||||
static const char *cmd_conn_read_state_limit(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
long int limit;
|
||||
@@ -1689,10 +1750,21 @@ static const char *cmd_conn_read_state_limit(cmd_parms *cmd, void *_dcfg,
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
limit = strtol(p1, NULL, 10);
|
||||
if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecReadStateLimit: %s", p1);
|
||||
if ((limit == LONG_MAX) || (limit == LONG_MIN) || (limit <= 0)) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for " \
|
||||
"SecReadStateLimit: %s", p1);
|
||||
}
|
||||
|
||||
if (p2 != NULL) {
|
||||
char *param = parser_conn_limits_operator(cmd->pool, p2,
|
||||
&conn_read_state_whitelist, &conn_read_state_whitelist_param,
|
||||
&conn_read_state_suspicious_list,
|
||||
&conn_read_state_suspicious_list_param, cmd->directive->filename);
|
||||
|
||||
if (param)
|
||||
return param;
|
||||
}
|
||||
|
||||
conn_read_state_limit = limit;
|
||||
|
||||
return NULL;
|
||||
@@ -1704,12 +1776,13 @@ static const char *cmd_conn_read_state_limit(cmd_parms *cmd, void *_dcfg,
|
||||
* \param cmd Pointer to configuration data
|
||||
* \param _dcfg Pointer to directory configuration
|
||||
* \param p1 Pointer to configuration option
|
||||
* \param p2 Pointer to configuration option
|
||||
*
|
||||
* \retval NULL On failure
|
||||
* \retval apr_psprintf On Success
|
||||
*/
|
||||
static const char *cmd_conn_write_state_limit(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
long int limit;
|
||||
@@ -1717,8 +1790,19 @@ static const char *cmd_conn_write_state_limit(cmd_parms *cmd, void *_dcfg,
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
limit = strtol(p1, NULL, 10);
|
||||
if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecWriteStateLimit: %s", p1);
|
||||
if ((limit == LONG_MAX) || (limit == LONG_MIN) || (limit <= 0)) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for " \
|
||||
"SecWriteStateLimit: %s", p1);
|
||||
}
|
||||
|
||||
if (p2 != NULL) {
|
||||
char *param = parser_conn_limits_operator(cmd->pool, p2,
|
||||
&conn_write_state_whitelist, &conn_write_state_whitelist_param,
|
||||
&conn_write_state_suspicious_list,
|
||||
&conn_write_state_suspicious_list_param, cmd->directive->filename);
|
||||
|
||||
if (param)
|
||||
return param;
|
||||
}
|
||||
|
||||
conn_write_state_limit = limit;
|
||||
@@ -3192,7 +3276,7 @@ const command_rec module_directives[] = {
|
||||
"Threshold to log slow rules in usecs."
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
AP_INIT_TAKE12 (
|
||||
"SecReadStateLimit",
|
||||
cmd_conn_read_state_limit,
|
||||
NULL,
|
||||
@@ -3200,7 +3284,7 @@ const command_rec module_directives[] = {
|
||||
"maximum number of threads in READ_BUSY state per ip address"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
AP_INIT_TAKE12 (
|
||||
"SecWriteStateLimit",
|
||||
cmd_conn_write_state_limit,
|
||||
NULL,
|
||||
|
Reference in New Issue
Block a user