Raw value of arguments from request string can help for XSS.
src/http/ngx_http_variables.c | 134
+++++++++++++++++++++++++++++++++++++++++
1 files changed, 134 insertions(+), 0 deletions(-)
diff --git a/src/http/ngx_http_variables.c
b/src/http/ngx_http_variables.c
index
22f213cf6157ab5b99e481835acf9a394ef21919…035f6cc4687d20646d156d0ed58a303aef76b8d8
100644
— a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -31,6 +31,10 @@ 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_urlencode(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_urldecode(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 +534,24 @@ ngx_http_get_variable(ngx_http_request_t *r,
ngx_str_t *name, ngx_uint_t key,
}
#endif
- if (ngx_strncmp(name->data, “urlencode_”, 10) == 0) {
-
if (ngx_http_variable_urlencode(r, vv, (uintptr_t) name) ==
NGX_OK) {
-
return vv; -
} -
return NULL; - }
- if (ngx_strncmp(name->data, “urldecode_”, 10) == 0) {
-
if (ngx_http_variable_urldecode(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 +853,104 @@ ngx_http_variable_ssi(ngx_http_request_t *r,
ngx_http_variable_value_t *v,
static ngx_int_t
+ngx_http_variable_urlencode(ngx_http_request_t *r,
ngx_http_variable_value_t *v,
- uintptr_t data)
+{ - ngx_str_t *name = (ngx_str_t *) data;
- ngx_str_t sub_name;
- ngx_uint_t key;
- ngx_http_variable_value_t *vv;
- sub_name.len = name->len - (sizeof(“urlencode_”) - 1);
- sub_name.data = name->data + sizeof(“urlencode_”) - 1;
- key = ngx_hash_strlow(sub_name.data, sub_name.data, sub_name.len);
- vv = ngx_http_get_variable(r, &sub_name, key, 0);
- if (vv == NULL || !vv->valid) {
-
return NGX_ERROR; - }
- if (vv->not_found) {
-
v->not_found = 1; -
return NGX_OK; - }
- v->len = vv->len +
- 2 * ngx_escape_uri(NULL, vv->data, vv->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, vv->data, vv->len, NGX_ESCAPE_ARGS);
- v->valid = 1;
- v->not_found = 0;
- v->no_cacheable = vv->no_cacheable;
- return NGX_OK;
+}
+static ngx_int_t
+ngx_http_variable_urldecode(ngx_http_request_t *r,
ngx_http_variable_value_t *v,
- uintptr_t data)
+{ - ngx_str_t *name = (ngx_str_t *) data;
- u_char *dst, *src;
- ngx_str_t sub_name;
- ngx_uint_t key;
- ngx_http_variable_value_t *vv;
- sub_name.len = name->len - (sizeof(“urldecode_”) - 1);
- sub_name.data = name->data + sizeof(“urldecode_”) - 1;
- key = ngx_hash_strlow(sub_name.data, sub_name.data, sub_name.len);
- vv = ngx_http_get_variable(r, &sub_name, key, 0);
- if (vv == NULL || !vv->valid) {
-
return NGX_ERROR; - }
- if (vv->not_found) {
-
v->not_found = 1; -
return NGX_OK; - }
- v->len = vv->len;
- v->data = ngx_palloc(r->pool, v->len);
- if (v->data == NULL) {
-
v->not_found = 1; -
return NGX_OK; - }
- dst = v->data;
- src = vv->data;
- ngx_unescape_uri(&dst, &src, vv->len, NGX_ESCAPE_ARGS);
- v->len = dst - v->data;
- v->valid = 1;
- v->not_found = 0;
- v->no_cacheable = vv->no_cacheable;
- 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 +1909,20 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
}
#endif
-
if (ngx_strncmp(v[i].name.data, "urlencode_", 10) == 0) { -
v[i].get_handler = ngx_http_variable_urlencode; -
v[i].data = (uintptr_t) &v[i].name; -
continue; -
} -
if (ngx_strncmp(v[i].name.data, "urldecode_", 10) == 0) { -
v[i].get_handler = ngx_http_variable_urldecode; -
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;