diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2019-07-12 15:35:31 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2019-07-12 15:35:31 +0300 |
commit | cae2e689083a04b2ddbb93bef5313b136080df65 (patch) | |
tree | 01f68ae8abb66a0969a3702df9f84f04278614bc /src | |
parent | 19887831698e18149a45a8b9563e8fdcdaaea211 (diff) | |
download | nginx-cae2e689083a04b2ddbb93bef5313b136080df65.tar.gz nginx-cae2e689083a04b2ddbb93bef5313b136080df65.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/http/modules/perl/nginx.xs | 44 | ||||
-rw-r--r-- | src/http/modules/perl/ngx_http_perl_module.c | 5 | ||||
-rw-r--r-- | src/http/modules/perl/ngx_http_perl_module.h | 1 |
3 files changed, 50 insertions, 0 deletions
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs index e9db2f7d6..67ec0a564 100644 --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -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"); } diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c index ac6a7a2a3..a383e9002 100644 --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -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; diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h index 5c967dfb3..b67ce137c 100644 --- a/src/http/modules/perl/ngx_http_perl_module.h +++ b/src/http/modules/perl/ngx_http_perl_module.h @@ -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 */ |