Welcome! Log In Create A New Profile

Advanced

[njs] HTTP: validating URI and args arguments in r.subrequest().

Dmitry Volyntsev
April 02, 2024 12:14PM
details: https://hg.nginx.org/njs/rev/2d6d9d1e8b8f
branches:
changeset: 2308:2d6d9d1e8b8f
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Tue Apr 02 08:52:56 2024 -0700
description:
HTTP: validating URI and args arguments in r.subrequest().

diffstat:

nginx/ngx_http_js_module.c | 37 +++++++++++++++++++++++++++++++++++++
nginx/t/js_subrequests.t | 40 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 75 insertions(+), 2 deletions(-)

diffs (138 lines):

diff -r 17af51d42ad9 -r 2d6d9d1e8b8f nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c Mon Apr 01 23:13:25 2024 -0700
+++ b/nginx/ngx_http_js_module.c Tue Apr 02 08:52:56 2024 -0700
@@ -305,6 +305,9 @@ static char *ngx_http_js_merge_loc_conf(
static ngx_ssl_t *ngx_http_js_ssl(njs_vm_t *vm, ngx_http_request_t *r);
static ngx_flag_t ngx_http_js_ssl_verify(njs_vm_t *vm, ngx_http_request_t *r);

+static ngx_int_t ngx_http_js_parse_unsafe_uri(ngx_http_request_t *r,
+ njs_str_t *uri, njs_str_t *args);
+
#if (NGX_HTTP_SSL)

static ngx_conf_bitmask_t ngx_http_js_ssl_protocols[] = {
@@ -3272,6 +3275,11 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
}
}

+ if (ngx_http_js_parse_unsafe_uri(r, &uri_arg, &args_arg) != NGX_OK) {
+ njs_vm_error(vm, "unsafe uri");
+ return NJS_ERROR;
+ }
+
arg = njs_arg(args, nargs, 3);

if (callback == NULL && !njs_value_is_undefined(arg)) {
@@ -4979,3 +4987,32 @@ ngx_http_js_ssl_verify(njs_vm_t *vm, ngx
return 0;
#endif
}
+
+
+static ngx_int_t
+ngx_http_js_parse_unsafe_uri(ngx_http_request_t *r, njs_str_t *uri,
+ njs_str_t *args)
+{
+ ngx_str_t uri_arg, args_arg;
+ ngx_uint_t flags;
+
+ flags = NGX_HTTP_LOG_UNSAFE;
+
+ uri_arg.data = uri->start;
+ uri_arg.len = uri->length;
+
+ args_arg.data = args->start;
+ args_arg.len = args->length;
+
+ if (ngx_http_parse_unsafe_uri(r, &uri_arg, &args_arg, &flags) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ uri->start = uri_arg.data;
+ uri->length = uri_arg.len;
+
+ args->start = args_arg.data;
+ args->length = args_arg.len;
+
+ return NGX_OK;
+}
diff -r 17af51d42ad9 -r 2d6d9d1e8b8f nginx/t/js_subrequests.t
--- a/nginx/t/js_subrequests.t Mon Apr 01 23:13:25 2024 -0700
+++ b/nginx/t/js_subrequests.t Tue Apr 02 08:52:56 2024 -0700
@@ -148,6 +148,10 @@ http {
js_content test.sr_unavail_pr;
}

+ location /sr_unsafe {
+ js_content test.sr_unsafe;
+ }
+
location /sr_broken {
js_content test.sr_broken;
}
@@ -385,6 +389,11 @@ EOF
subrequest_fn_pr(req, ['/unavail'], ['uri', 'status']);
}

+ function sr_unsafe(r) {
+ r.subrequest('../dir');
+ r.return(200);
+ }
+
function sr_broken(r) {
r.subrequest('/daemon/unfinished', reply => {
r.return(200, JSON.stringify({code:reply.status}));
@@ -498,13 +507,14 @@ EOF
sr_unavail_pr, sr_broken, sr_too_large, sr_in_sr,
sr_js_in_subrequest, sr_js_in_subrequest_pr, js_sub,
sr_in_sr_callback, sr_out_of_order, sr_except_not_a_func,
- sr_uri_except, sr_except_failed_to_convert_options_arg};
+ sr_uri_except, sr_except_failed_to_convert_options_arg,
+ sr_unsafe};

EOF

$t->write_file('t', '["SEE-THIS"]');

-$t->try_run('no njs available')->plan(32);
+$t->try_run('no njs available')->plan(33);
$t->run_daemon(\&http_daemon);

###############################################################################
@@ -558,6 +568,13 @@ is(get_json('/sr_in_sr_callback'),
'{"e":"subrequest can only be created for the primary request"}',
'subrequest for non-primary request');

+TODO: {
+local $TODO = 'not yet' unless has_version('0.8.4');
+
+like(http_get('/sr_unsafe'), qr/500/s, 'unsafe subrequest uri');
+
+}
+
$t->stop();

ok(index($t->read_file('error.log'), 'callback is not a function') > 0,
@@ -634,3 +651,22 @@ sub http_daemon {
}

###############################################################################
+
+sub has_version {
+ my $need = shift;
+
+ http_get('/njs') =~ /^([.0-9]+)$/m;
+
+ my @v = split(/\./, $1);
+ my ($n, $v);
+
+ for $n (split(/\./, $need)) {
+ $v = shift @v || 0;
+ return 0 if $n > $v;
+ return 1 if $v > $n;
+ }
+
+ return 1;
+}
+
+###############################################################################
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] HTTP: validating URI and args arguments in r.subrequest().

Dmitry Volyntsev 191 April 02, 2024 12:14PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 113
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready