r1299 merge:
msie_refresh should escape at least '"' to prevent XSS
This commit is contained in:
parent
149fdb18d8
commit
32ad363a2c
3 changed files with 43 additions and 16 deletions
|
@ -1039,18 +1039,30 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
|
||||||
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* " ", """, "'", %00-%1F, %7F-%FF */
|
||||||
|
|
||||||
switch (type) {
|
static uint32_t refresh[] = {
|
||||||
case NGX_ESCAPE_HTML:
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
escape = html;
|
|
||||||
break;
|
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||||
case NGX_ESCAPE_ARGS:
|
0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */
|
||||||
escape = args;
|
|
||||||
break;
|
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||||
default:
|
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
escape = uri;
|
|
||||||
break;
|
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||||
}
|
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t *map[] = { uri, args, html, refresh };
|
||||||
|
|
||||||
|
|
||||||
|
escape = map[type];
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@ u_char *ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n);
|
||||||
#define NGX_ESCAPE_URI 0
|
#define NGX_ESCAPE_URI 0
|
||||||
#define NGX_ESCAPE_ARGS 1
|
#define NGX_ESCAPE_ARGS 1
|
||||||
#define NGX_ESCAPE_HTML 2
|
#define NGX_ESCAPE_HTML 2
|
||||||
|
#define NGX_ESCAPE_REFRESH 3
|
||||||
|
|
||||||
#define NGX_UNESCAPE_URI 1
|
#define NGX_UNESCAPE_URI 1
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
size_t msie_refresh;
|
size_t msie_refresh;
|
||||||
|
uintptr_t escape;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_str_t *uri, *location;
|
ngx_str_t *uri, *location;
|
||||||
|
@ -496,17 +497,19 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
||||||
r->headers_out.content_length = NULL;
|
r->headers_out.content_length = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
msie_refresh = 0;
|
|
||||||
location = NULL;
|
|
||||||
|
|
||||||
if (clcf->msie_refresh
|
if (clcf->msie_refresh
|
||||||
&& r->headers_in.msie
|
&& r->headers_in.msie
|
||||||
&& (error == NGX_HTTP_MOVED_PERMANENTLY
|
&& (error == NGX_HTTP_MOVED_PERMANENTLY
|
||||||
|| error == NGX_HTTP_MOVED_TEMPORARILY))
|
|| error == NGX_HTTP_MOVED_TEMPORARILY))
|
||||||
{
|
{
|
||||||
|
|
||||||
location = &r->headers_out.location->value;
|
location = &r->headers_out.location->value;
|
||||||
|
|
||||||
|
escape = 2 * ngx_escape_uri(NULL, location->data, location->len,
|
||||||
|
NGX_ESCAPE_REFRESH);
|
||||||
|
|
||||||
msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1
|
msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1
|
||||||
+ location->len
|
+ escape + location->len
|
||||||
+ sizeof(ngx_http_msie_refresh_tail) - 1;
|
+ sizeof(ngx_http_msie_refresh_tail) - 1;
|
||||||
|
|
||||||
r->err_status = NGX_HTTP_OK;
|
r->err_status = NGX_HTTP_OK;
|
||||||
|
@ -514,6 +517,11 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
||||||
r->headers_out.content_length_n = msie_refresh;
|
r->headers_out.content_length_n = msie_refresh;
|
||||||
r->headers_out.location->hash = 0;
|
r->headers_out.location->hash = 0;
|
||||||
r->headers_out.location = NULL;
|
r->headers_out.location = NULL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
location = NULL;
|
||||||
|
escape = 0;
|
||||||
|
msie_refresh = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_http_clear_accept_ranges(r);
|
ngx_http_clear_accept_ranges(r);
|
||||||
|
@ -595,7 +603,13 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
||||||
p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
|
p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
|
||||||
sizeof(ngx_http_msie_refresh_head) - 1);
|
sizeof(ngx_http_msie_refresh_head) - 1);
|
||||||
|
|
||||||
p = ngx_cpymem(p, location->data, location->len);
|
if (escape == 0) {
|
||||||
|
p = ngx_cpymem(p, location->data, location->len);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
p = (u_char *) ngx_escape_uri(p, location->data, location->len,
|
||||||
|
NGX_ESCAPE_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
|
b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
|
||||||
sizeof(ngx_http_msie_refresh_tail) - 1);
|
sizeof(ngx_http_msie_refresh_tail) - 1);
|
||||||
|
|
Loading…
Reference in a new issue