18
18
19
19
#include <apr_base64.h>
20
20
21
-
22
21
/* Those are defined twice, lets keep it defined just once by `undef`
23
22
* the first one.
24
23
*/
31
30
#define NOTE_NGINX_REQUEST_CTX "nginx-ctx"
32
31
#define TXID_SIZE 25
33
32
33
+ /*
34
+ * If MOVE_REQUEST_CHAIN_TO_MODSEC is set, the chain will be moved into the
35
+ * ModSecurity brigade, after be processed by ModSecurity, it needs to be moved
36
+ * to nginx chains again, in order to be processed by other modules. It seems
37
+ * that this is not working well whenever the request body is delivered into
38
+ * chunks. Resulting in segfaults.
39
+ *
40
+ * If MOVE_REQUEST_CHAIN_TO_MODSEC is _not_ set, a copy of the request body
41
+ * will be delivered to ModSecurity and after processed it will be released,
42
+ * not modifying the nginx chain.
43
+ *
44
+ * The malfunctioning can be observer while running the following regression
45
+ * tests:
46
+ * #15 - SecRequestBodyInMemoryLimit
47
+ * #16 - SecRequestBodyInMemoryLimit (greater)
48
+ * #19 - SecRequestBodyLimitAction ProcessPartial (multipart/greater - chunked)
49
+ * (from: regression/config/10-request-directives.t)
50
+ */
51
+ /*
52
+ #define MOVE_REQUEST_CHAIN_TO_MODSEC
53
+ */
54
+
55
+
34
56
#define tuxb
35
57
36
58
/*
@@ -492,8 +514,8 @@ ngx_http_modsecurity_save_headers_in_visitor(void *data, const char *key, const
492
514
static ngx_inline ngx_int_t
493
515
ngx_http_modsecurity_load_request_body (ngx_http_request_t * r )
494
516
{
495
- ngx_http_modsecurity_ctx_t * ctx ;
496
-
517
+ ngx_http_modsecurity_ctx_t * ctx ;
518
+ ngx_chain_t * chain ;
497
519
498
520
ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
499
521
"ModSec: loading request body." );
@@ -502,33 +524,47 @@ ngx_http_modsecurity_load_request_body(ngx_http_request_t *r)
502
524
503
525
modsecSetBodyBrigade (ctx -> req , ctx -> brigade );
504
526
505
- if (r -> request_body == NULL || r -> request_body -> bufs == NULL ) {
506
- ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
507
- "ModSec: request was null." );
508
-
509
- return move_chain_to_brigade (NULL , ctx -> brigade , r -> pool , 1 );
527
+ if (r -> request_body == NULL ) {
528
+ chain = NULL ;
510
529
}
530
+ else {
531
+ chain = r -> request_body -> bufs ;
532
+ }
533
+
511
534
512
- if (move_chain_to_brigade (r -> request_body -> bufs , ctx -> brigade , r -> pool , 1 ) != NGX_OK ) {
535
+ #ifdef MOVE_REQUEST_CHAIN_TO_MODSEC
536
+ if (move_chain_to_brigade (chain , ctx -> brigade , r -> pool , 1 ) != NGX_OK ) {
513
537
ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
514
538
"ModSec: failed to move chain to brigade." );
515
539
516
540
return NGX_ERROR ;
517
541
}
518
542
519
543
r -> request_body = NULL ;
544
+ #else
545
+ if (copy_chain_to_brigade (chain , ctx -> brigade , r -> pool , 1 ) != NGX_OK ) {
546
+ ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
547
+ "ModSec: failed to copy chain to brigade." );
548
+
549
+ return NGX_ERROR ;
550
+ }
551
+ #endif
520
552
521
553
return NGX_OK ;
522
554
}
523
555
524
556
static ngx_inline ngx_int_t
525
557
ngx_http_modsecurity_save_request_body (ngx_http_request_t * r )
526
558
{
527
- ngx_http_modsecurity_ctx_t * ctx ;
528
- apr_off_t content_length ;
529
- ngx_buf_t * buf ;
530
- ctx = ngx_http_get_module_ctx (r , ngx_http_modsecurity );
559
+ ngx_http_modsecurity_ctx_t * ctx ;
560
+ #ifdef MOVE_REQUEST_CHAIN_TO_MODSEC
561
+ apr_off_t content_length ;
562
+ ngx_buf_t * buf ;
563
+ #endif
564
+
565
+ ctx = ngx_http_get_module_ctx (r , ngx_http_modsecurity );
531
566
567
+ #ifdef MOVE_REQUEST_CHAIN_TO_MODSEC
532
568
apr_brigade_length (ctx -> brigade , 0 , & content_length );
533
569
534
570
buf = ngx_create_temp_buf (ctx -> r -> pool , (size_t ) content_length );
@@ -550,10 +586,15 @@ ngx_http_modsecurity_save_request_body(ngx_http_request_t *r)
550
586
551
587
}
552
588
553
-
554
589
r -> headers_in .content_length_n = content_length ;
555
590
556
- ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 , "ModSec: Content length: %O, Content length n: %O" , content_length , r -> headers_in .content_length_n );
591
+ ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
592
+ "ModSec: Content length: %O, Content length n: %O" , content_length ,
593
+ r -> headers_in .content_length_n );
594
+ #else
595
+ apr_brigade_cleanup (ctx -> brigade );
596
+ #endif
597
+
557
598
return NGX_OK ;
558
599
}
559
600
@@ -787,7 +828,7 @@ ngx_http_modsecurity_status(ngx_http_request_t *r, int status)
787
828
* @param r pointer to ngx_http_request_t.
788
829
*
789
830
*/
790
- static void
831
+ ngx_int_t
791
832
ngx_http_modsecurity_process_request (ngx_http_request_t * r )
792
833
{
793
834
ngx_int_t rc = 0 ;
@@ -802,23 +843,21 @@ ngx_http_modsecurity_process_request(ngx_http_request_t *r)
802
843
if (ngx_http_modsecurity_load_request (r ) != NGX_OK ) {
803
844
ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
804
845
"ModSec: failed while loading the request." );
805
- ngx_http_finalize_request (r , NGX_HTTP_INTERNAL_SERVER_ERROR );
806
- goto terminate ;
846
+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
807
847
}
808
848
809
849
if (ngx_http_modsecurity_load_headers_in (r ) != NGX_OK ) {
810
850
ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
811
851
"ModSec: failed while loading the headers." );
812
- ngx_http_finalize_request (r , NGX_HTTP_INTERNAL_SERVER_ERROR );
813
- goto terminate ;
852
+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
814
853
}
815
854
816
855
rc = modsecProcessRequestHeaders (ctx -> req );
817
856
rc = ngx_http_modsecurity_status (r , rc );
818
857
if (rc != NGX_DECLINED ) {
819
858
ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
820
859
"ModSec: failed while processing the request headers" );
821
- ngx_http_finalize_request ( r , rc ) ;
860
+ return rc ;
822
861
}
823
862
824
863
/* Here we check if ModSecurity is enabled or disabled again.
@@ -841,12 +880,15 @@ ngx_http_modsecurity_process_request(ngx_http_request_t *r)
841
880
}
842
881
843
882
if (load_request_body == 1 ) {
883
+ ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
884
+ "ModSec: loading request body..." );
885
+
844
886
rc = ngx_http_modsecurity_load_request_body (r );
845
887
if (rc != NGX_OK )
846
888
{
847
889
ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
848
890
"ModSec: failed while loading the request body." );
849
- ngx_http_finalize_request ( r , NGX_HTTP_INTERNAL_SERVER_ERROR ) ;
891
+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
850
892
}
851
893
852
894
@@ -862,24 +904,23 @@ ngx_http_modsecurity_process_request(ngx_http_request_t *r)
862
904
"ModSec: finalizing the connection after process the " \
863
905
"request body." );
864
906
865
- ngx_http_finalize_request ( r , rc ) ;
907
+ return rc ;
866
908
}
867
909
if (load_request_body == 1 ) {
868
910
if (ngx_http_modsecurity_save_request_body (r ) != NGX_OK )
869
911
{
870
912
ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
871
913
"ModSec: failed while saving the request body" );
872
- ngx_http_finalize_request ( r , NGX_HTTP_INTERNAL_SERVER_ERROR ) ;
914
+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
873
915
}
874
916
if (ngx_http_modsecurity_save_headers_in (r ) != NGX_OK )
875
917
{
876
918
ngx_log_debug (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
877
919
"ModSec: failed while saving the headers in" );
878
- ngx_http_finalize_request ( r , NGX_HTTP_INTERNAL_SERVER_ERROR ) ;
920
+ return NGX_HTTP_INTERNAL_SERVER_ERROR ;
879
921
}
880
922
}
881
- terminate :
882
- return ;
923
+ return NGX_OK ;
883
924
}
884
925
885
926
@@ -1102,14 +1143,22 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r) {
1102
1143
1103
1144
ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
1104
1145
"ModSec: request is ready to be processed." );
1105
- ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
1106
- "ModSec: chuncked? %d" , r -> chunked );
1107
- ngx_http_modsecurity_process_request (r );
1146
+ rc = ngx_http_modsecurity_process_request (r );
1108
1147
ctx -> request_processed = 1 ;
1148
+
1149
+ if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE ) {
1150
+ ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
1151
+ "ModSec: returning a special response after process " \
1152
+ "a request: %d" , rc );
1153
+
1154
+ return rc ;
1155
+ }
1156
+
1157
+
1109
1158
}
1110
1159
1111
1160
ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
1112
- "ModSec: returning NGX_OK. Count++ :P " );
1161
+ "ModSec: returning NGX_DECLINED. " );
1113
1162
1114
1163
return NGX_DECLINED ;
1115
1164
}
0 commit comments