mirror of
https://github.com/nginx/nginx.git
synced 2024-12-03 04:39:00 +08:00
Teach ngx_http_parse_unsafe_uri() how to unescape URIs.
This fixes handling of escaped URIs in X-Accel-Redirect (ticket #316), SSI (ticket #240), and DAV.
This commit is contained in:
parent
336bcb22d1
commit
f7ff5e65d0
@ -1982,8 +1982,6 @@ static ngx_int_t
|
||||
ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
u_char *dst, *src;
|
||||
size_t len;
|
||||
ngx_int_t rc, key;
|
||||
ngx_str_t *uri, *file, *wait, *set, *stub, args;
|
||||
ngx_buf_t *b;
|
||||
@ -2054,18 +2052,6 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
return rc;
|
||||
}
|
||||
|
||||
dst = uri->data;
|
||||
src = uri->data;
|
||||
|
||||
ngx_unescape_uri(&dst, &src, uri->len, NGX_UNESCAPE_URI);
|
||||
|
||||
len = (uri->data + uri->len) - src;
|
||||
if (len) {
|
||||
dst = ngx_movemem(dst, src, len);
|
||||
}
|
||||
|
||||
uri->len = dst - uri->data;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"ssi include: \"%V\"", uri);
|
||||
|
||||
|
@ -1780,11 +1780,13 @@ ngx_int_t
|
||||
ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
ngx_str_t *args, ngx_uint_t *flags)
|
||||
{
|
||||
u_char ch, *p;
|
||||
size_t len;
|
||||
u_char ch, *p, *src, *dst;
|
||||
size_t len;
|
||||
ngx_uint_t quoted;
|
||||
|
||||
len = uri->len;
|
||||
p = uri->data;
|
||||
quoted = 0;
|
||||
|
||||
if (len == 0 || p[0] == '?') {
|
||||
goto unsafe;
|
||||
@ -1800,6 +1802,11 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
|
||||
ch = *p++;
|
||||
|
||||
if (ch == '%') {
|
||||
quoted = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
|
||||
continue;
|
||||
}
|
||||
@ -1809,7 +1816,7 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
args->data = p;
|
||||
uri->len -= len;
|
||||
|
||||
return NGX_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == '\0') {
|
||||
@ -1828,6 +1835,56 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
}
|
||||
}
|
||||
|
||||
if (quoted) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"escaped URI: \"%V\"", uri);
|
||||
|
||||
src = uri->data;
|
||||
|
||||
dst = ngx_pnalloc(r->pool, uri->len);
|
||||
if (dst == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
uri->data = dst;
|
||||
|
||||
ngx_unescape_uri(&dst, &src, uri->len, 0);
|
||||
|
||||
uri->len = dst - uri->data;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"unescaped URI: \"%V\"", uri);
|
||||
|
||||
len = uri->len;
|
||||
p = uri->data;
|
||||
|
||||
if (p[0] == '.' && len > 1 && p[1] == '.'
|
||||
&& (len == 2 || ngx_path_separator(p[2])))
|
||||
{
|
||||
goto unsafe;
|
||||
}
|
||||
|
||||
for ( /* void */ ; len; len--) {
|
||||
|
||||
ch = *p++;
|
||||
|
||||
if (ch == '\0') {
|
||||
goto unsafe;
|
||||
}
|
||||
|
||||
if (ngx_path_separator(ch) && len > 2) {
|
||||
|
||||
/* detect "/../" and "/.." */
|
||||
|
||||
if (p[0] == '.' && p[1] == '.'
|
||||
&& (len == 3 || ngx_path_separator(p[2])))
|
||||
{
|
||||
goto unsafe;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
unsafe:
|
||||
|
Loading…
Reference in New Issue
Block a user