r1299 merge:

msie_refresh should escape at least '"' to prevent XSS
This commit is contained in:
Igor Sysoev 2007-07-17 09:34:23 +00:00
parent 149fdb18d8
commit 32ad363a2c
3 changed files with 43 additions and 16 deletions

View file

@ -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) {

View file

@ -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

View file

@ -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);