details: https://hg.nginx.org/nginx/rev/0cb693b4cbbb branches: changeset: 7528:0cb693b4cbbb user: Maxim Dounin <mdou...@mdounin.ru> date: Fri Jul 12 15:35:31 2019 +0300 description: 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: src/http/modules/perl/nginx.xs | 44 ++++++++++++++++++++++++++++ src/http/modules/perl/ngx_http_perl_module.c | 5 +++ src/http/modules/perl/ngx_http_perl_module.h | 1 + 3 files changed, 50 insertions(+), 0 deletions(-) diffs (164 lines): diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- 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 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 --- 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_ 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_ 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_ 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 --- 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 */ _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel