Skip to content

Commit 755011c

Browse files
authored
Merge branch 'master' into master
2 parents 7b8d7de + 1c32794 commit 755011c

21 files changed

+331
-75
lines changed

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ addons:
1616
- liblmdb-dev
1717

1818
env:
19-
- VER_NGINX=1.17.6
20-
- VER_NGINX=1.16.1
19+
- VER_NGINX=1.21.0
20+
- VER_NGINX=1.20.1
2121

2222
before_script:
2323
- cd ..

CHANGES

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
v1.0.x - YYYY-MMM-DD (To be released)
2-
-------------------------------------
2+
--------------------
33

44
- Support http protocol versions besides 0.9, 1.0, 1.1, 2.0
55
[Issue #224 - @HQuest, @martinhsv]
6+
- Support for building with nginx configured with PCRE2
7+
[Issue #260 - @defanator]
8+
9+
v1.0.2 - 2021-Jun-02
10+
--------------------
11+
12+
- Fix auditlog in case of internal redirect
13+
[Issue #90 - @AirisX, @defanator]
14+
- Fix nginx sends response without headers
15+
[Issue #238 - @airween, @defanator]
616
- Fix nginx not clearing body cache (caused by incomplete fix for #187)
717
[Issue #216 - @krewi1, @martinhsv]
818
- Fix config setting not respected: client_body_in_file_only on

src/ngx_http_modsecurity_body_filter.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
5656
return ngx_http_next_body_filter(r, in);
5757
}
5858

59+
if (ctx->intervention_triggered) {
60+
return ngx_http_next_body_filter(r, in);
61+
}
62+
5963
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
6064
mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
6165
if (mcf != NULL && mcf->sanity_checks_enabled != NGX_CONF_UNSET)
@@ -141,7 +145,7 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
141145
int ret;
142146

143147
msc_append_response_body(ctx->modsec_transaction, data, chain->buf->last - data);
144-
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
148+
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
145149
if (ret > 0) {
146150
return ngx_http_filter_finalize_request(r,
147151
&ngx_http_modsecurity_module, ret);
@@ -159,7 +163,7 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
159163

160164
/* XXX: I don't get how body from modsec being transferred to nginx's buffer. If so - after adjusting of nginx's
161165
XXX: body we can proceed to adjust body size (content-length). see xslt_body_filter() for example */
162-
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
166+
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
163167
if (ret > 0) {
164168
return ret;
165169
}

src/ngx_http_modsecurity_common.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
#define MODSECURITY_NGINX_MAJOR "1"
5858
#define MODSECURITY_NGINX_MINOR "0"
59-
#define MODSECURITY_NGINX_PATCHLEVEL "1"
59+
#define MODSECURITY_NGINX_PATCHLEVEL "2"
6060
#define MODSECURITY_NGINX_TAG ""
6161
#define MODSECURITY_NGINX_TAG_NUM "100"
6262

@@ -97,6 +97,8 @@ typedef struct {
9797
unsigned waiting_more_body:1;
9898
unsigned body_requested:1;
9999
unsigned processed:1;
100+
unsigned logged:1;
101+
unsigned intervention_triggered:1;
100102
} ngx_http_modsecurity_ctx_t;
101103

102104

@@ -135,11 +137,16 @@ typedef struct {
135137
extern ngx_module_t ngx_http_modsecurity_module;
136138

137139
/* ngx_http_modsecurity_module.c */
138-
int ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_request_t *r);
140+
int ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_request_t *r, ngx_int_t early_log);
139141
ngx_http_modsecurity_ctx_t *ngx_http_modsecurity_create_ctx(ngx_http_request_t *r);
140142
char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p);
143+
#if (NGX_PCRE2)
144+
#define ngx_http_modsecurity_pcre_malloc_init(x) NULL
145+
#define ngx_http_modsecurity_pcre_malloc_done(x) (void)x
146+
#else
141147
ngx_pool_t *ngx_http_modsecurity_pcre_malloc_init(ngx_pool_t *pool);
142148
void ngx_http_modsecurity_pcre_malloc_done(ngx_pool_t *old_pool);
149+
#endif
143150

144151
/* ngx_http_modsecurity_body_filter.c */
145152
ngx_int_t ngx_http_modsecurity_body_filter_init(void);
@@ -149,7 +156,7 @@ ngx_int_t ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *i
149156
ngx_int_t ngx_http_modsecurity_header_filter_init(void);
150157
ngx_int_t ngx_http_modsecurity_header_filter(ngx_http_request_t *r);
151158
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
152-
int ngx_http_modescurity_store_ctx_header(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value);
159+
int ngx_http_modsecurity_store_ctx_header(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value);
153160
#endif
154161

155162
/* ngx_http_modsecurity_log.c */

src/ngx_http_modsecurity_header_filter.c

+18-14
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ ngx_http_modsecurity_header_out_t ngx_http_modsecurity_headers_out[] = {
101101

102102
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
103103
int
104-
ngx_http_modescurity_store_ctx_header(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value)
104+
ngx_http_modsecurity_store_ctx_header(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value)
105105
{
106106
ngx_http_modsecurity_ctx_t *ctx;
107107
ngx_http_modsecurity_conf_t *mcf;
@@ -167,7 +167,7 @@ ngx_http_modsecurity_resolv_header_server(ngx_http_request_t *r, ngx_str_t name,
167167
}
168168

169169
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
170-
ngx_http_modescurity_store_ctx_header(r, &name, &value);
170+
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
171171
#endif
172172

173173
return msc_add_n_response_header(ctx->modsec_transaction,
@@ -196,7 +196,7 @@ ngx_http_modsecurity_resolv_header_date(ngx_http_request_t *r, ngx_str_t name, o
196196
}
197197

198198
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
199-
ngx_http_modescurity_store_ctx_header(r, &name, &date);
199+
ngx_http_modsecurity_store_ctx_header(r, &name, &date);
200200
#endif
201201

202202
return msc_add_n_response_header(ctx->modsec_transaction,
@@ -223,7 +223,7 @@ ngx_http_modsecurity_resolv_header_content_length(ngx_http_request_t *r, ngx_str
223223
value.len = strlen(buf);
224224

225225
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
226-
ngx_http_modescurity_store_ctx_header(r, &name, &value);
226+
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
227227
#endif
228228
return msc_add_n_response_header(ctx->modsec_transaction,
229229
(const unsigned char *) name.data,
@@ -247,7 +247,7 @@ ngx_http_modsecurity_resolv_header_content_type(ngx_http_request_t *r, ngx_str_t
247247
{
248248

249249
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
250-
ngx_http_modescurity_store_ctx_header(r, &name, &r->headers_out.content_type);
250+
ngx_http_modsecurity_store_ctx_header(r, &name, &r->headers_out.content_type);
251251
#endif
252252

253253
return msc_add_n_response_header(ctx->modsec_transaction,
@@ -280,7 +280,7 @@ ngx_http_modsecurity_resolv_header_last_modified(ngx_http_request_t *r, ngx_str_
280280
value.len = (int)(p-buf);
281281

282282
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
283-
ngx_http_modescurity_store_ctx_header(r, &name, &value);
283+
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
284284
#endif
285285

286286
return msc_add_n_response_header(ctx->modsec_transaction,
@@ -316,7 +316,7 @@ ngx_http_modsecurity_resolv_header_connection(ngx_http_request_t *r, ngx_str_t n
316316
value.len = strlen((char *)buf);
317317

318318
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
319-
ngx_http_modescurity_store_ctx_header(r, &name2, &value);
319+
ngx_http_modsecurity_store_ctx_header(r, &name2, &value);
320320
#endif
321321

322322
msc_add_n_response_header(ctx->modsec_transaction,
@@ -333,7 +333,7 @@ ngx_http_modsecurity_resolv_header_connection(ngx_http_request_t *r, ngx_str_t n
333333
value.len = strlen(connection);
334334

335335
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
336-
ngx_http_modescurity_store_ctx_header(r, &name, &value);
336+
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
337337
#endif
338338

339339
return msc_add_n_response_header(ctx->modsec_transaction,
@@ -354,7 +354,7 @@ ngx_http_modsecurity_resolv_header_transfer_encoding(ngx_http_request_t *r, ngx_
354354
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
355355

356356
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
357-
ngx_http_modescurity_store_ctx_header(r, &name, &value);
357+
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
358358
#endif
359359

360360
return msc_add_n_response_header(ctx->modsec_transaction,
@@ -381,7 +381,7 @@ ngx_http_modsecurity_resolv_header_vary(ngx_http_request_t *r, ngx_str_t name, o
381381
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
382382

383383
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
384-
ngx_http_modescurity_store_ctx_header(r, &name, &value);
384+
ngx_http_modsecurity_store_ctx_header(r, &name, &value);
385385
#endif
386386

387387
return msc_add_n_response_header(ctx->modsec_transaction,
@@ -430,6 +430,10 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r)
430430
return ngx_http_next_header_filter(r);
431431
}
432432

433+
if (ctx->intervention_triggered) {
434+
return ngx_http_next_header_filter(r);
435+
}
436+
433437
/* XXX: can it happen ? already processed i mean */
434438
/* XXX: check behaviour on 'ModSecurity off' */
435439

@@ -488,7 +492,7 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r)
488492
}
489493

490494
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
491-
ngx_http_modescurity_store_ctx_header(r, &data[i].key, &data[i].value);
495+
ngx_http_modsecurity_store_ctx_header(r, &data[i].key, &data[i].value);
492496
#endif
493497

494498
/*
@@ -522,12 +526,12 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r)
522526
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
523527
msc_process_response_headers(ctx->modsec_transaction, status, http_response_ver);
524528
ngx_http_modsecurity_pcre_malloc_done(old_pool);
525-
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
529+
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
526530
if (r->error_page) {
527531
return ngx_http_next_header_filter(r);
528-
}
532+
}
529533
if (ret > 0) {
530-
return ret;
534+
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity_module, ret);
531535
}
532536

533537
/*

src/ngx_http_modsecurity_log.c

+5
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ ngx_http_modsecurity_log_handler(ngx_http_request_t *r)
6767
return NGX_ERROR;
6868
}
6969

70+
if (ctx->logged) {
71+
dd("already logged earlier");
72+
return NGX_OK;
73+
}
74+
7075
dd("calling msc_process_logging for %p", ctx);
7176
old_pool = ngx_http_modsecurity_pcre_malloc_init(r->pool);
7277
msc_process_logging(ctx->modsec_transaction);

src/ngx_http_modsecurity_module.c

+25-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ static void ngx_http_modsecurity_cleanup_rules(void *data);
3838
* https://github.com/openresty/lua-nginx-module/blob/master/src/ngx_http_lua_pcrefix.c
3939
*/
4040

41+
#if !(NGX_PCRE2)
4142
static void *(*old_pcre_malloc)(size_t);
4243
static void (*old_pcre_free)(void *ptr);
4344
static ngx_pool_t *ngx_http_modsec_pcre_pool = NULL;
@@ -103,6 +104,7 @@ ngx_http_modsecurity_pcre_malloc_done(ngx_pool_t *old_pool)
103104
pcre_free = old_pcre_free;
104105
}
105106
}
107+
#endif
106108

107109
/*
108110
* ngx_string's are not null-terminated in common case, so we need to convert
@@ -130,17 +132,24 @@ ngx_inline char *ngx_str_to_char(ngx_str_t a, ngx_pool_t *p)
130132

131133

132134
ngx_inline int
133-
ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_request_t *r)
135+
ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_request_t *r, ngx_int_t early_log)
134136
{
135137
char *log = NULL;
136138
ModSecurityIntervention intervention;
137139
intervention.status = 200;
138140
intervention.url = NULL;
139141
intervention.log = NULL;
140142
intervention.disruptive = 0;
143+
ngx_http_modsecurity_ctx_t *ctx = NULL;
141144

142145
dd("processing intervention");
143146

147+
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module);
148+
if (ctx == NULL)
149+
{
150+
return NGX_HTTP_INTERNAL_SERVER_ERROR;
151+
}
152+
144153
if (msc_intervention(transaction, &intervention) == 0) {
145154
dd("nothing to do");
146155
return 0;
@@ -192,14 +201,28 @@ ngx_http_modsecurity_process_intervention (Transaction *transaction, ngx_http_re
192201
r->headers_out.location->hash = 1;
193202

194203
#if defined(MODSECURITY_SANITY_CHECKS) && (MODSECURITY_SANITY_CHECKS)
195-
ngx_http_modescurity_store_ctx_header(r, &location->key, &location->value);
204+
ngx_http_modsecurity_store_ctx_header(r, &location->key, &location->value);
196205
#endif
197206

198207
return intervention.status;
199208
}
200209

201210
if (intervention.status != 200)
202211
{
212+
/**
213+
* FIXME: this will bring proper response code to audit log in case
214+
* when e.g. error_page redirect was triggered, but there still won't be another
215+
* required pieces like response headers etc.
216+
*
217+
*/
218+
msc_update_status_code(ctx->modsec_transaction, intervention.status);
219+
220+
if (early_log) {
221+
dd("intervention -- calling log handler manually with code: %d", intervention.status);
222+
ngx_http_modsecurity_log_handler(r);
223+
ctx->logged = 1;
224+
}
225+
203226
if (r->header_sent)
204227
{
205228
dd("Headers are already sent. Cannot perform the redirection at this point.");

src/ngx_http_modsecurity_pre_access.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r)
7878
return NGX_HTTP_INTERNAL_SERVER_ERROR;
7979
}
8080

81+
if (ctx->intervention_triggered) {
82+
return NGX_DECLINED;
83+
}
84+
8185
if (ctx->waiting_more_body == 1)
8286
{
8387
dd("waiting for more data before proceed. / count: %d",
@@ -189,7 +193,7 @@ ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r)
189193
* it may ask for a intervention in consequence of that.
190194
*
191195
*/
192-
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
196+
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
193197
if (ret > 0) {
194198
return ret;
195199
}
@@ -208,7 +212,7 @@ ngx_http_modsecurity_pre_access_handler(ngx_http_request_t *r)
208212
msc_process_request_body(ctx->modsec_transaction);
209213
ngx_http_modsecurity_pcre_malloc_done(old_pool);
210214

211-
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
215+
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 0);
212216
if (r->error_page) {
213217
return NGX_DECLINED;
214218
}

src/ngx_http_modsecurity_rewrite.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,9 @@ ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
115115
*
116116
*/
117117
dd("Processing intervention with the connection information filled in");
118-
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
118+
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 1);
119119
if (ret > 0) {
120+
ctx->intervention_triggered = 1;
120121
return ret;
121122
}
122123

@@ -163,8 +164,9 @@ ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
163164
ngx_http_modsecurity_pcre_malloc_done(old_pool);
164165

165166
dd("Processing intervention with the transaction information filled in (uri, method and version)");
166-
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
167+
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 1);
167168
if (ret > 0) {
169+
ctx->intervention_triggered = 1;
168170
return ret;
169171
}
170172

@@ -211,11 +213,12 @@ ngx_http_modsecurity_rewrite_handler(ngx_http_request_t *r)
211213
msc_process_request_headers(ctx->modsec_transaction);
212214
ngx_http_modsecurity_pcre_malloc_done(old_pool);
213215
dd("Processing intervention with the request headers information filled in");
214-
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r);
216+
ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r, 1);
215217
if (r->error_page) {
216218
return NGX_DECLINED;
217219
}
218220
if (ret > 0) {
221+
ctx->intervention_triggered = 1;
219222
return ret;
220223
}
221224
}

0 commit comments

Comments
 (0)