mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2026-01-15 07:57:10 +03:00
2.5.13-dev3 and SecReadStateLimit
This commit is contained in:
7
CHANGES
7
CHANGES
@@ -1,3 +1,10 @@
|
|||||||
|
22 Nov 2010 - 2.5.13-dev3
|
||||||
|
|
||||||
|
* Add SecReadStateLimit to limit the number of BUSY connections
|
||||||
|
|
||||||
|
* Fixed redirect action was not expanding macros in chained rules
|
||||||
|
|
||||||
|
|
||||||
04 Nov 2010 - 2.5.13-dev2
|
04 Nov 2010 - 2.5.13-dev2
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
|||||||
@@ -1343,6 +1343,34 @@ static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg,
|
|||||||
return NULL;
|
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
|
||||||
|
*
|
||||||
|
* \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)
|
||||||
|
{
|
||||||
|
directory_config *dcfg = (directory_config *)_dcfg;
|
||||||
|
long int limit;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn_read_state_limit = limit;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg,
|
static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg,
|
||||||
const char *p1)
|
const char *p1)
|
||||||
{
|
{
|
||||||
@@ -2208,6 +2236,14 @@ const command_rec module_directives[] = {
|
|||||||
"On or Off"
|
"On or Off"
|
||||||
),
|
),
|
||||||
|
|
||||||
|
AP_INIT_TAKE1 (
|
||||||
|
"SecReadStateLimit",
|
||||||
|
cmd_conn_read_state_limit,
|
||||||
|
NULL,
|
||||||
|
CMD_SCOPE_ANY,
|
||||||
|
"maximum number of server in busy state"
|
||||||
|
),
|
||||||
|
|
||||||
AP_INIT_TAKE1 (
|
AP_INIT_TAKE1 (
|
||||||
"SecRequestBodyInMemoryLimit",
|
"SecRequestBodyInMemoryLimit",
|
||||||
cmd_request_body_inmemory_limit,
|
cmd_request_body_inmemory_limit,
|
||||||
|
|||||||
@@ -54,6 +54,15 @@ unsigned long int DSOLOCAL msc_pcre_match_limit = 0;
|
|||||||
|
|
||||||
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
|
unsigned long int DSOLOCAL msc_pcre_match_limit_recursion = 0;
|
||||||
|
|
||||||
|
unsigned long int DSOLOCAL conn_read_state_limit = 0;
|
||||||
|
|
||||||
|
static int server_limit, thread_limit;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int child_num;
|
||||||
|
int thread_num;
|
||||||
|
} sb_handle;
|
||||||
|
|
||||||
/* -- Miscellaneous functions -- */
|
/* -- Miscellaneous functions -- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1060,6 +1069,61 @@ static void modsec_register_operator(const char *name, void *fn_init, void *fn_e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \brief Connetion hook to limit the number of
|
||||||
|
* connections in BUSY state
|
||||||
|
*
|
||||||
|
* \param conn Pointer to connection struct
|
||||||
|
*
|
||||||
|
* \retval DECLINED On failure
|
||||||
|
* \retval OK On Success
|
||||||
|
*/
|
||||||
|
static int hook_connection_early(conn_rec *conn)
|
||||||
|
{
|
||||||
|
sb_handle *sb = conn->sbh;
|
||||||
|
int i, j;
|
||||||
|
int ip_count = 0;
|
||||||
|
int limit = 0;
|
||||||
|
worker_score *ws_record = NULL;
|
||||||
|
|
||||||
|
if(sb != NULL && conn_read_state_limit > 0) {
|
||||||
|
|
||||||
|
ws_record = &ap_scoreboard_image->servers[sb->child_num][sb->thread_num];
|
||||||
|
if(ws_record == NULL)
|
||||||
|
return DECLINED;
|
||||||
|
|
||||||
|
apr_cpystrn(ws_record->client, conn->remote_ip, sizeof(ws_record->client));
|
||||||
|
|
||||||
|
for (i = 0; i < server_limit; ++i) {
|
||||||
|
for (j = 0; j < thread_limit; ++j) {
|
||||||
|
|
||||||
|
ws_record = ap_get_scoreboard_worker(i, j);
|
||||||
|
|
||||||
|
if(ws_record == NULL)
|
||||||
|
return DECLINED;
|
||||||
|
|
||||||
|
switch (ws_record->status) {
|
||||||
|
case SERVER_BUSY_READ:
|
||||||
|
if (strcmp(conn->remote_ip, ws_record->client) == 0)
|
||||||
|
ip_count++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip_count > conn_read_state_limit) {
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, "ModSecurity: Access denied with code 400. Too many connections [%d] of %ld allowed in READ state from %s - Possible DoS Consumption Attack [Rejected]", ip_count,conn_read_state_limit,conn->remote_ip);
|
||||||
|
return OK;
|
||||||
|
} else {
|
||||||
|
return DECLINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is exported for other Apache modules to
|
* This function is exported for other Apache modules to
|
||||||
* register new variables.
|
* register new variables.
|
||||||
@@ -1117,6 +1181,10 @@ static void register_hooks(apr_pool_t *mp) {
|
|||||||
APR_REGISTER_OPTIONAL_FN(modsec_register_variable);
|
APR_REGISTER_OPTIONAL_FN(modsec_register_variable);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For connection level hook */
|
||||||
|
ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
|
||||||
|
ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
|
||||||
|
|
||||||
/* Main hooks */
|
/* Main hooks */
|
||||||
ap_hook_pre_config(hook_pre_config, NULL, NULL, APR_HOOK_FIRST);
|
ap_hook_pre_config(hook_pre_config, NULL, NULL, APR_HOOK_FIRST);
|
||||||
ap_hook_post_config(hook_post_config, postconfig_beforeme_list,
|
ap_hook_post_config(hook_post_config, postconfig_beforeme_list,
|
||||||
@@ -1127,6 +1195,9 @@ static void register_hooks(apr_pool_t *mp) {
|
|||||||
* // ap_hook_handler(hook_handler, NULL, NULL, APR_HOOK_MIDDLE);
|
* // ap_hook_handler(hook_handler, NULL, NULL, APR_HOOK_MIDDLE);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Connection processing hooks */
|
||||||
|
ap_hook_process_connection(hook_connection_early, NULL, NULL, APR_HOOK_FIRST);
|
||||||
|
|
||||||
/* Transaction processing hooks */
|
/* Transaction processing hooks */
|
||||||
ap_hook_post_read_request(hook_request_early,
|
ap_hook_post_read_request(hook_request_early,
|
||||||
postread_beforeme_list, postread_afterme_list, APR_HOOK_REALLY_FIRST);
|
postread_beforeme_list, postread_afterme_list, APR_HOOK_REALLY_FIRST);
|
||||||
|
|||||||
@@ -131,6 +131,8 @@ extern DSOLOCAL unsigned long int msc_pcre_match_limit;
|
|||||||
|
|
||||||
extern DSOLOCAL unsigned long int msc_pcre_match_limit_recursion;
|
extern DSOLOCAL unsigned long int msc_pcre_match_limit_recursion;
|
||||||
|
|
||||||
|
extern DSOLOCAL unsigned long int conn_read_state_limit;
|
||||||
|
|
||||||
#define RESBODY_STATUS_NOT_READ 0 /* we were not configured to read the body */
|
#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_ERROR 1 /* error occured while we were reading the body */
|
||||||
#define RESBODY_STATUS_PARTIAL 2 /* partial body content available in the brigade */
|
#define RESBODY_STATUS_PARTIAL 2 /* partial body content available in the brigade */
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ extern DSOLOCAL modsec_build_type_rec modsec_build_type[];
|
|||||||
#define MODSEC_VERSION_MINOR "5"
|
#define MODSEC_VERSION_MINOR "5"
|
||||||
#define MODSEC_VERSION_MAINT "13"
|
#define MODSEC_VERSION_MAINT "13"
|
||||||
#define MODSEC_VERSION_TYPE "dev"
|
#define MODSEC_VERSION_TYPE "dev"
|
||||||
#define MODSEC_VERSION_RELEASE "2"
|
#define MODSEC_VERSION_RELEASE "3"
|
||||||
|
|
||||||
#define MODSEC_VERSION_SUFFIX MODSEC_VERSION_TYPE MODSEC_VERSION_RELEASE
|
#define MODSEC_VERSION_SUFFIX MODSEC_VERSION_TYPE MODSEC_VERSION_RELEASE
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user