changeset 7528:0cb693b4cbbb

Perl: disabled unrelated calls from variable handlers. Variable handlers are not expected to send anything to the client, cannot sleep or read body, and are not expected to modify the request. Added appropriate protection to prevent accidental foot shooting.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 12 Jul 2019 15:35:31 +0300
parents 02cd116ebe2a
children d758d04e0790
files src/http/modules/perl/nginx.xs src/http/modules/perl/ngx_http_perl_module.c src/http/modules/perl/ngx_http_perl_module.h
diffstat 3 files changed, 50 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/modules/perl/nginx.xs	Fri Jul 12 15:34:37 2019 +0300
+++ b/src/http/modules/perl/nginx.xs	Fri Jul 12 15:35:31 2019 +0300
@@ -110,6 +110,10 @@
 
     ngx_http_perl_set_request(r, ctx);
 
+    if (ctx->variable) {
+        croak("status(): cannot be used in variable handler");
+    }
+
     r->headers_out.status = SvIV(ST(1));
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -133,6 +137,10 @@
         croak("send_http_header(): called after error");
     }
 
+    if (ctx->variable) {
+        croak("send_http_header(): cannot be used in variable handler");
+    }
+
     if (r->headers_out.status == 0) {
         r->headers_out.status = NGX_HTTP_OK;
     }
@@ -400,6 +408,10 @@
 
     ngx_http_perl_set_request(r, ctx);
 
+    if (ctx->variable) {
+        croak("has_request_body(): cannot be used in variable handler");
+    }
+
     if (ctx->next) {
         croak("has_request_body(): another handler active");
     }
@@ -526,6 +538,10 @@
 
     ngx_http_perl_set_request(r, ctx);
 
+    if (ctx->variable) {
+        croak("discard_request_body(): cannot be used in variable handler");
+    }
+
     rc = ngx_http_discard_request_body(r);
 
     if (rc != NGX_OK) {
@@ -551,6 +567,10 @@
         croak("header_out(): called after error");
     }
 
+    if (ctx->variable) {
+        croak("header_out(): cannot be used in variable handler");
+    }
+
     key = ST(1);
     value = ST(2);
 
@@ -640,6 +660,10 @@
         croak("print(): called after error");
     }
 
+    if (ctx->variable) {
+        croak("print(): cannot be used in variable handler");
+    }
+
     if (items == 2) {
 
         /*
@@ -750,6 +774,10 @@
         croak("sendfile(): called after error");
     }
 
+    if (ctx->variable) {
+        croak("sendfile(): cannot be used in variable handler");
+    }
+
     filename = SvPV_nolen(ST(1));
 
     if (filename == NULL) {
@@ -852,6 +880,10 @@
         croak("flush(): called after error");
     }
 
+    if (ctx->variable) {
+        croak("flush(): cannot be used in variable handler");
+    }
+
     b = ngx_calloc_buf(r->pool);
     if (b == NULL) {
         ctx->error = 1;
@@ -883,6 +915,10 @@
 
     ngx_http_perl_set_request(r, ctx);
 
+    if (ctx->variable) {
+        croak("internal_redirect(): cannot be used in variable handler");
+    }
+
     uri = ST(1);
 
     if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) {
@@ -911,6 +947,10 @@
 
     ngx_http_perl_set_request(r, ctx);
 
+    if (ctx->variable) {
+        croak("allow_ranges(): cannot be used in variable handler");
+    }
+
     r->allow_ranges = 1;
 
 
@@ -1097,6 +1137,10 @@
 
     ngx_http_perl_set_request(r, ctx);
 
+    if (ctx->variable) {
+        croak("sleep(): cannot be used in variable handler");
+    }
+
     if (ctx->next) {
         croak("sleep(): another handler active");
     }
--- a/src/http/modules/perl/ngx_http_perl_module.c	Fri Jul 12 15:34:37 2019 +0300
+++ b/src/http/modules/perl/ngx_http_perl_module.c	Fri Jul 12 15:35:31 2019 +0300
@@ -302,6 +302,7 @@
 
     ngx_int_t                   rc;
     ngx_str_t                   value;
+    ngx_uint_t                  saved;
     ngx_http_perl_ctx_t        *ctx;
     ngx_http_perl_main_conf_t  *pmcf;
 
@@ -321,6 +322,9 @@
         ctx->request = r;
     }
 
+    saved = ctx->variable;
+    ctx->variable = 1;
+
     pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);
 
     value.data = NULL;
@@ -347,6 +351,7 @@
         v->not_found = 1;
     }
 
+    ctx->variable = saved;
     ctx->filename.data = NULL;
     ctx->redirect_uri.len = 0;
 
--- a/src/http/modules/perl/ngx_http_perl_module.h	Fri Jul 12 15:34:37 2019 +0300
+++ b/src/http/modules/perl/ngx_http_perl_module.h	Fri Jul 12 15:35:31 2019 +0300
@@ -33,6 +33,7 @@
 
     unsigned                  done:1;
     unsigned                  error:1;
+    unsigned                  variable:1;
 
     ngx_array_t              *variables;  /* array of ngx_http_perl_var_t */