]> git.kaiwu.me - nginx.git/commitdiff
Perl: disabled unrelated calls from variable handlers.
authorMaxim Dounin <mdounin@mdounin.ru>
Fri, 12 Jul 2019 12:35:31 +0000 (15:35 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Fri, 12 Jul 2019 12:35:31 +0000 (15:35 +0300)
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.

src/http/modules/perl/nginx.xs
src/http/modules/perl/ngx_http_perl_module.c
src/http/modules/perl/ngx_http_perl_module.h

index e9db2f7d6bf2422d04b37c9b9e18c00ae34b5127..67ec0a56427ff271422ebac2cbae2ba9f3265582 100644 (file)
@@ -110,6 +110,10 @@ status(r, code)
 
     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 @@ send_http_header(r, ...)
         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 @@ has_request_body(r, next)
 
     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 @@ discard_request_body(r)
 
     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 @@ header_out(r, key, value)
         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 @@ print(r, ...)
         croak("print(): called after error");
     }
 
+    if (ctx->variable) {
+        croak("print(): cannot be used in variable handler");
+    }
+
     if (items == 2) {
 
         /*
@@ -750,6 +774,10 @@ sendfile(r, filename, offset = -1, bytes = 0)
         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 @@ flush(r)
         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 @@ internal_redirect(r, uri)
 
     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 @@ allow_ranges(r)
 
     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 @@ sleep(r, sleep, next)
 
     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");
     }
index ac6a7a2a32216f9dccfae4577d3b198e0de6fed2..a383e9002ee7a02a38eebc65c9e0339622e20247 100644 (file)
@@ -302,6 +302,7 @@ ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 
     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 @@ ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
         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 @@ ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
         v->not_found = 1;
     }
 
+    ctx->variable = saved;
     ctx->filename.data = NULL;
     ctx->redirect_uri.len = 0;
 
index 5c967dfb323529122c94b4d840e4a0154162e538..b67ce137cc5bd7047ac5cb30bd8ade5a786d50ef 100644 (file)
@@ -33,6 +33,7 @@ typedef struct {
 
     unsigned                  done:1;
     unsigned                  error:1;
+    unsigned                  variable:1;
 
     ngx_array_t              *variables;  /* array of ngx_http_perl_var_t */