comparison src/http/ngx_http_special_response.c @ 320:95183808f549 NGINX_0_6_4

nginx 0.6.4 *) Security: the "msie_refresh" directive allowed XSS. Thanks to Maxim Boguk. *) Change: the "proxy_store" and "fastcgi_store" directives were changed. *) Feature: the "proxy_store_access" and "fastcgi_store_access" directives. *) Bugfix: nginx did not work on Solaris/sparc64 if it was built by Sun Studio. Thanks to Andrei Nigmatulin. *) Workaround: for Sun Studio 12. Thanks to Jiang Hong.
author Igor Sysoev <http://sysoev.ru>
date Tue, 17 Jul 2007 00:00:00 +0400
parents c5c2b2883984
children f7cd062ee035
comparison
equal deleted inserted replaced
319:6ccd0af7f704 320:95183808f549
313 ngx_int_t 313 ngx_int_t
314 ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) 314 ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
315 { 315 {
316 u_char *p; 316 u_char *p;
317 size_t msie_refresh; 317 size_t msie_refresh;
318 uintptr_t escape;
318 ngx_int_t rc; 319 ngx_int_t rc;
319 ngx_buf_t *b; 320 ngx_buf_t *b;
320 ngx_str_t *uri, *location; 321 ngx_str_t *uri, *location;
321 ngx_uint_t i, n, err, msie_padding; 322 ngx_uint_t i, n, err, msie_padding;
322 ngx_chain_t *out, *cl; 323 ngx_chain_t *out, *cl;
494 if (r->headers_out.content_length) { 495 if (r->headers_out.content_length) {
495 r->headers_out.content_length->hash = 0; 496 r->headers_out.content_length->hash = 0;
496 r->headers_out.content_length = NULL; 497 r->headers_out.content_length = NULL;
497 } 498 }
498 499
499 msie_refresh = 0;
500 location = NULL;
501
502 if (clcf->msie_refresh 500 if (clcf->msie_refresh
503 && r->headers_in.msie 501 && r->headers_in.msie
504 && (error == NGX_HTTP_MOVED_PERMANENTLY 502 && (error == NGX_HTTP_MOVED_PERMANENTLY
505 || error == NGX_HTTP_MOVED_TEMPORARILY)) 503 || error == NGX_HTTP_MOVED_TEMPORARILY))
506 { 504 {
505
507 location = &r->headers_out.location->value; 506 location = &r->headers_out.location->value;
507
508 escape = 2 * ngx_escape_uri(NULL, location->data, location->len,
509 NGX_ESCAPE_REFRESH);
510
508 msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1 511 msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1
509 + location->len 512 + escape + location->len
510 + sizeof(ngx_http_msie_refresh_tail) - 1; 513 + sizeof(ngx_http_msie_refresh_tail) - 1;
511 514
512 r->err_status = NGX_HTTP_OK; 515 r->err_status = NGX_HTTP_OK;
513 r->headers_out.content_type_len = sizeof("text/html") - 1; 516 r->headers_out.content_type_len = sizeof("text/html") - 1;
514 r->headers_out.content_length_n = msie_refresh; 517 r->headers_out.content_length_n = msie_refresh;
515 r->headers_out.location->hash = 0; 518 r->headers_out.location->hash = 0;
516 r->headers_out.location = NULL; 519 r->headers_out.location = NULL;
520
521 } else {
522 location = NULL;
523 escape = 0;
524 msie_refresh = 0;
517 } 525 }
518 526
519 ngx_http_clear_accept_ranges(r); 527 ngx_http_clear_accept_ranges(r);
520 ngx_http_clear_last_modified(r); 528 ngx_http_clear_last_modified(r);
521 529
593 } 601 }
594 602
595 p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head, 603 p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
596 sizeof(ngx_http_msie_refresh_head) - 1); 604 sizeof(ngx_http_msie_refresh_head) - 1);
597 605
598 p = ngx_cpymem(p, location->data, location->len); 606 if (escape == 0) {
607 p = ngx_cpymem(p, location->data, location->len);
608
609 } else {
610 p = (u_char *) ngx_escape_uri(p, location->data, location->len,
611 NGX_ESCAPE_REFRESH);
612 }
599 613
600 b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail, 614 b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
601 sizeof(ngx_http_msie_refresh_tail) - 1); 615 sizeof(ngx_http_msie_refresh_tail) - 1);
602 616
603 cl = ngx_alloc_chain_link(r->pool); 617 cl = ngx_alloc_chain_link(r->pool);