From 2291530197c84f8a7c38775659295bd8cc1c7ee1 Mon Sep 17 00:00:00 2001 From: Kirill A. Korinskiy Date: Wed, 25 Mar 2009 20:11:48 +0300 Subject: [PATCH] Implements the $encoded_arg_ variables for get url encode value of argument from request string. Cc: catap@catap.ru Raw value of arguments from request string can help for XSS. --- src/http/ngx_http_variables.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-) diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 22f213cf6157ab5b99e481835acf9a394ef21919..c8990ac7d283020835547be71f05b55a940152f3 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -31,6 +31,8 @@ static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r, static ngx_int_t ngx_http_variable_ssi(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); #endif +static ngx_int_t ngx_http_variable_encoded_argument(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); @@ -530,6 +532,15 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key, } #endif + if (ngx_strncmp(name->data, "encoded_arg_", 12) == 0) { + + if (ngx_http_variable_encoded_argument(r, vv, (uintptr_t) name) == NGX_OK) { + return vv; + } + + return NULL; + } + if (ngx_strncmp(name->data, "arg_", 4) == 0) { if (ngx_http_variable_argument(r, vv, (uintptr_t) name) == NGX_OK) { @@ -831,6 +842,42 @@ ngx_http_variable_ssi(ngx_http_request_t *r, ngx_http_variable_value_t *v, static ngx_int_t +ngx_http_variable_encoded_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v, + uintptr_t data) +{ + ngx_str_t *name = (ngx_str_t *) data; + + u_char *arg; + size_t len; + ngx_str_t value; + + len = name->len - (sizeof("encoded_arg_") - 1); + arg = name->data + sizeof("encoded_arg_") - 1; + + if (ngx_http_arg(r, arg, len, &value) != NGX_OK) { + v->not_found = 1; + return NGX_OK; + } + + v->len = value.len + + 2 * ngx_escape_uri(NULL, value.data, value.len, NGX_ESCAPE_ARGS); + + v->data = ngx_palloc(r->pool, v->len); + if (v->data == NULL) { + v->not_found = 1; + return NGX_OK; + } + + (void) ngx_escape_uri(v->data, value.data, value.len, NGX_ESCAPE_ARGS); + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -1789,6 +1836,13 @@ ngx_http_variables_init_vars(ngx_conf_t *cf) } #endif + if (ngx_strncmp(v[i].name.data, "encoded_arg_", 12) == 0) { + v[i].get_handler = ngx_http_variable_encoded_argument; + v[i].data = (uintptr_t) &v[i].name; + + continue; + } + if (ngx_strncmp(v[i].name.data, "arg_", 4) == 0) { v[i].get_handler = ngx_http_variable_argument; v[i].data = (uintptr_t) &v[i].name; -- 1.6.2