From 6815d1769051c123b3d3e92da44338c5d47925d2 Mon Sep 17 00:00:00 2001 From: chaizhenhua Date: Thu, 20 Dec 2012 10:39:23 +0800 Subject: [PATCH] Added drop action for nginx --- apache2/mod_security2.c | 27 +++++++++++++++++++----- nginx/modsecurity/ngx_http_modsecurity.c | 17 +++++++++++++++ standalone/api.c | 6 +++++- standalone/api.h | 2 +- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 05de75b69d..6b41088186 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -64,6 +64,9 @@ unsigned long int DSOLOCAL conn_read_state_limit = 0; unsigned long int DSOLOCAL conn_write_state_limit = 0; +#if defined(WIN32) || defined(VERSION_NGINX) +int (*modsecDropAction)(request_rec *r) = NULL; +#endif static int server_limit, thread_limit; typedef struct { @@ -250,11 +253,25 @@ int perform_interception(modsec_rec *msr) { } } #else - log_level = 1; - status = HTTP_INTERNAL_SERVER_ERROR; - message = apr_psprintf(msr->mp, "Access denied with code 500%s " - "(Error: Connection drop not implemented on this platform).", - phase_text); + { + if (modsecDropAction == NULL) { + log_level = 1; + status = HTTP_INTERNAL_SERVER_ERROR; + message = apr_psprintf(msr->mp, "Access denied with code 500%s " + "(Error: Connection drop not implemented on this platform.", + phase_text); + } else if (modsecDropAction(msr->r) == 0) { + status = HTTP_FORBIDDEN; + message = apr_psprintf(msr->mp, "Access denied with connection close%s.", + phase_text); + } else { + log_level = 1; + status = HTTP_INTERNAL_SERVER_ERROR; + message = apr_psprintf(msr->mp, "Access denied with code 500%s " + "(Error: Connection drop request failed.", + phase_text); + } + } #endif break; diff --git a/nginx/modsecurity/ngx_http_modsecurity.c b/nginx/modsecurity/ngx_http_modsecurity.c index 683727b497..a6cd4b578c 100644 --- a/nginx/modsecurity/ngx_http_modsecurity.c +++ b/nginx/modsecurity/ngx_http_modsecurity.c @@ -81,6 +81,8 @@ static char *ngx_http_modsecurity_add_handler(ngx_conf_t *cf, ngx_command_t *cmd static char *ngx_http_modsecurity_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_int_t ngx_http_modsecurity_pass_to_backend(ngx_http_request_t *r); +static int ngx_http_modsecurity_drop_action(request_rec *r); + /* command handled by the module */ static ngx_command_t ngx_http_modsecurity_commands[] = { { ngx_string("ModSecurityConfig"), @@ -223,6 +225,8 @@ ngx_http_modsecurity_init_process(ngx_cycle_t *cycle) modsecSetLogHook(cycle->log, modsecLog); + modsecSetDropAction(ngx_http_modsecurity_drop_action); + modsecInit(); /* config was already parsed in master process */ // modsecStartConfig(); @@ -1094,3 +1098,16 @@ ngx_http_modsecurity_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_OK; } + +static int +ngx_http_modsecurity_drop_action(request_rec *r) +{ + ngx_http_modsecurity_ctx_t *ctx; + ctx = (ngx_http_modsecurity_ctx_t *) apr_table_get(r->notes, NOTE_NGINX_REQUEST_CTX); + + if (ctx == NULL) { + return -1; + } + ctx->r->connection->error = 1; + return 0; +} diff --git a/standalone/api.c b/standalone/api.c index 5a08d8e333..806c5daf44 100644 --- a/standalone/api.c +++ b/standalone/api.c @@ -41,7 +41,7 @@ extern void *modsecLogObj; extern void (*modsecLogHook)(void *obj, int level, char *str); - +extern int (*modsecDropAction)(request_rec *r); apr_status_t (*modsecReadBody)(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos); apr_status_t (*modsecReadResponse)(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos); apr_status_t (*modsecWriteBody)(request_rec *r, char *buf, unsigned int length); @@ -528,3 +528,7 @@ void modsecSetWriteBody(apr_status_t (*func)(request_rec *r, char *buf, unsigned void modsecSetWriteResponse(apr_status_t (*func)(request_rec *r, char *buf, unsigned int length)) { modsecWriteResponse = func; } + +void modsecSetDropAction(int (*func)(request_rec *r)) { + modsecDropAction = func; +} diff --git a/standalone/api.h b/standalone/api.h index 49a5f1637c..825f722cc4 100644 --- a/standalone/api.h +++ b/standalone/api.h @@ -70,7 +70,7 @@ void modsecSetReadBody(apr_status_t (*func)(request_rec *r, char *buf, unsigned void modsecSetReadResponse(apr_status_t (*func)(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos)); void modsecSetWriteBody(apr_status_t (*func)(request_rec *r, char *buf, unsigned int length)); void modsecSetWriteResponse(apr_status_t (*func)(request_rec *r, char *buf, unsigned int length)); - +void modsecSetDropAction(int (*func)(request_rec *r)); int modsecIsResponseBodyAccessEnabled(request_rec *r); #ifdef __cplusplus