From f388a2e5840b8f8353dae0d71951a3c7d3871e76 Mon Sep 17 00:00:00 2001 From: Liu Dongmiao Date: Mon, 21 Mar 2022 20:24:18 +0800 Subject: [PATCH 1/2] terminated for status 101 (like websocket) If server responsed 101, it will switch to other tcp protocol. There is no http request / response any more. This patch will free transaction when received status 101. Nginx will free the ctx when connection terminates. --- src/ngx_http_modsecurity_body_filter.c | 14 ++++++++++++++ src/ngx_http_modsecurity_common.h | 1 + src/ngx_http_modsecurity_module.c | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/src/ngx_http_modsecurity_body_filter.c b/src/ngx_http_modsecurity_body_filter.c index 725f986..e4f6912 100644 --- a/src/ngx_http_modsecurity_body_filter.c +++ b/src/ngx_http_modsecurity_body_filter.c @@ -56,6 +56,11 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in) return ngx_http_next_body_filter(r, in); } + if (ctx->modsec_transaction == NULL) { + // we have freed the modsec_transaction + return ngx_http_next_body_filter(r, in); + } + if (ctx->intervention_triggered) { return ngx_http_next_body_filter(r, in); } @@ -179,6 +184,15 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in) dd("buffer was not fully loaded! ctx: %p", ctx); } + if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) { + dd("it's switching protocols, clean transaction for %p", ctx); + // I don't think there are any response body + ngx_http_modsecurity_log_handler(r); + ctx->logged = 1; + + ngx_http_modsecurity_cleanup(ctx); + } + /* XXX: xflt_filter() -- return NGX_OK here */ return ngx_http_next_body_filter(r, in); } diff --git a/src/ngx_http_modsecurity_common.h b/src/ngx_http_modsecurity_common.h index 60218c4..313bdfe 100644 --- a/src/ngx_http_modsecurity_common.h +++ b/src/ngx_http_modsecurity_common.h @@ -142,6 +142,7 @@ ngx_http_modsecurity_ctx_t *ngx_http_modsecurity_create_ctx(ngx_http_request_t * char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p); ngx_pool_t *ngx_http_modsecurity_pcre_malloc_init(ngx_pool_t *pool); void ngx_http_modsecurity_pcre_malloc_done(ngx_pool_t *old_pool); +void ngx_http_modsecurity_cleanup(void *data); /* ngx_http_modsecurity_body_filter.c */ ngx_int_t ngx_http_modsecurity_body_filter_init(void); diff --git a/src/ngx_http_modsecurity_module.c b/src/ngx_http_modsecurity_module.c index b6f33f5..f2d204d 100644 --- a/src/ngx_http_modsecurity_module.c +++ b/src/ngx_http_modsecurity_module.c @@ -240,7 +240,12 @@ ngx_http_modsecurity_cleanup(void *data) ctx = (ngx_http_modsecurity_ctx_t *) data; + if (!ctx->modsec_transaction) { + // it's already clean in 101 + return; + } msc_transaction_cleanup(ctx->modsec_transaction); + ctx->modsec_transaction = NULL; #if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS) /* From 1f94f833370a645938850e63f4468b4da91fb7ef Mon Sep 17 00:00:00 2001 From: Liu Dongmiao Date: Wed, 31 Aug 2022 09:55:22 +0800 Subject: [PATCH 2/2] avoid dependency on ctx->logged --- src/ngx_http_modsecurity_body_filter.c | 1 - src/ngx_http_modsecurity_log.c | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ngx_http_modsecurity_body_filter.c b/src/ngx_http_modsecurity_body_filter.c index e4f6912..5b7abce 100644 --- a/src/ngx_http_modsecurity_body_filter.c +++ b/src/ngx_http_modsecurity_body_filter.c @@ -188,7 +188,6 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in) dd("it's switching protocols, clean transaction for %p", ctx); // I don't think there are any response body ngx_http_modsecurity_log_handler(r); - ctx->logged = 1; ngx_http_modsecurity_cleanup(ctx); } diff --git a/src/ngx_http_modsecurity_log.c b/src/ngx_http_modsecurity_log.c index d713a65..f9f1410 100644 --- a/src/ngx_http_modsecurity_log.c +++ b/src/ngx_http_modsecurity_log.c @@ -72,6 +72,11 @@ ngx_http_modsecurity_log_handler(ngx_http_request_t *r) return NGX_OK; } + if (!ctx->modsec_transaction) { + // it's already clean and logged in 101 + return NGX_OK; + } + dd("calling msc_process_logging for %p", ctx); old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool); msc_process_logging(ctx->modsec_transaction);