From d5b5ebfbd51f0ae033b7c613f407ce6c59cc1667 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Tue, 2 Jul 2024 16:40:12 +0200 Subject: [PATCH] New variable $modsecurity_status This variable can be used for example in access logs to distinguish which requests was blocked by modsecurity --- src/ngx_http_modsecurity_common.h | 1 + src/ngx_http_modsecurity_module.c | 52 ++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/ngx_http_modsecurity_common.h b/src/ngx_http_modsecurity_common.h index d69d87e..13f961d 100644 --- a/src/ngx_http_modsecurity_common.h +++ b/src/ngx_http_modsecurity_common.h @@ -99,6 +99,7 @@ typedef struct { unsigned processed:1; unsigned logged:1; unsigned intervention_triggered:1; + ngx_uint_t status; // status code from modsecurity } ngx_http_modsecurity_ctx_t; diff --git a/src/ngx_http_modsecurity_module.c b/src/ngx_http_modsecurity_module.c index ec091f4..54b31e6 100644 --- a/src/ngx_http_modsecurity_module.c +++ b/src/ngx_http_modsecurity_module.c @@ -36,7 +36,10 @@ static void *ngx_http_modsecurity_create_conf(ngx_conf_t *cf); static char *ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child); static void ngx_http_modsecurity_cleanup_instance(void *data); static void ngx_http_modsecurity_cleanup_rules(void *data); +static ngx_int_t ngx_http_modsecurity_add_variables(ngx_conf_t *cf); +static ngx_int_t ngx_http_modsecurity_status_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_str_t ngx_http_modsecurity_status = ngx_string("modsecurity_status"); /* * PCRE malloc/free workaround, based on @@ -223,6 +226,7 @@ ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_re if (intervention.status != 200) { + ctx->status = intervention.status; /** * FIXME: this will bring proper response code to audit log in case * when e.g. error_page redirect was triggered, but there still won't be another @@ -284,6 +288,8 @@ ngx_http_modsecurity_create_ctx(ngx_http_request_t *r) return NULL; } + ctx->status = 0; + mmcf = ngx_http_get_module_main_conf(r, ngx_http_modsecurity_module); mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module); @@ -514,7 +520,7 @@ static ngx_command_t ngx_http_modsecurity_commands[] = { static ngx_http_module_t ngx_http_modsecurity_ctx = { - NULL, /* preconfiguration */ + ngx_http_modsecurity_add_variables, /* preconfiguration */ ngx_http_modsecurity_init, /* postconfiguration */ ngx_http_modsecurity_create_main_conf, /* create main configuration */ @@ -817,4 +823,48 @@ ngx_http_modsecurity_cleanup_rules(void *data) } +static ngx_int_t +ngx_http_modsecurity_add_variables(ngx_conf_t *cf) +{ + ngx_http_variable_t *v; + + v = ngx_http_add_variable(cf, &ngx_http_modsecurity_status, + NGX_HTTP_VAR_NOCACHEABLE); + if (v == NULL) { + return NGX_ERROR; + } + + v->get_handler = ngx_http_modsecurity_status_variable; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_modsecurity_status_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_http_modsecurity_ctx_t *ctx; + + ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module); + if (ctx == NULL || ctx->status == 0) { + v->not_found = 1; + return NGX_OK; + } + + v->data = ngx_pnalloc(r->pool, NGX_INT_T_LEN); + if (v->data == NULL) { + return NGX_ERROR; + } + + v->len = ngx_sprintf(v->data, "%03ui", ctx->status) - v->data; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + return NGX_OK; +} + + + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */