Mercurial > hg > nginx
comparison src/http/ngx_http_parse.c @ 7881:52338ddf9e2f
Disabled spaces in URIs (ticket #196).
From now on, requests with spaces in URIs are immediately rejected rather
than allowed. Spaces were allowed in 31e9677b15a1 (0.8.41) to handle bad
clients. It is believed that now this behaviour causes more harm than
good.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 28 Jun 2021 18:01:13 +0300 |
parents | 63c66b7cc07c |
children | b4073527be81 |
comparison
equal
deleted
inserted
replaced
7880:dfd8dfb436e5 | 7881:52338ddf9e2f |
---|---|
114 sw_host_start, | 114 sw_host_start, |
115 sw_host, | 115 sw_host, |
116 sw_host_end, | 116 sw_host_end, |
117 sw_host_ip_literal, | 117 sw_host_ip_literal, |
118 sw_port, | 118 sw_port, |
119 sw_host_http_09, | |
120 sw_after_slash_in_uri, | 119 sw_after_slash_in_uri, |
121 sw_check_uri, | 120 sw_check_uri, |
122 sw_check_uri_http_09, | |
123 sw_uri, | 121 sw_uri, |
124 sw_http_09, | 122 sw_http_09, |
125 sw_http_H, | 123 sw_http_H, |
126 sw_http_HT, | 124 sw_http_HT, |
127 sw_http_HTT, | 125 sw_http_HTT, |
396 * use single "/" from request line to preserve pointers, | 394 * use single "/" from request line to preserve pointers, |
397 * if request line will be copied to large client buffer | 395 * if request line will be copied to large client buffer |
398 */ | 396 */ |
399 r->uri_start = r->schema_end + 1; | 397 r->uri_start = r->schema_end + 1; |
400 r->uri_end = r->schema_end + 2; | 398 r->uri_end = r->schema_end + 2; |
401 state = sw_host_http_09; | 399 state = sw_http_09; |
402 break; | 400 break; |
403 default: | 401 default: |
404 return NGX_HTTP_PARSE_INVALID_REQUEST; | 402 return NGX_HTTP_PARSE_INVALID_REQUEST; |
405 } | 403 } |
406 break; | 404 break; |
470 * use single "/" from request line to preserve pointers, | 468 * use single "/" from request line to preserve pointers, |
471 * if request line will be copied to large client buffer | 469 * if request line will be copied to large client buffer |
472 */ | 470 */ |
473 r->uri_start = r->schema_end + 1; | 471 r->uri_start = r->schema_end + 1; |
474 r->uri_end = r->schema_end + 2; | 472 r->uri_end = r->schema_end + 2; |
475 state = sw_host_http_09; | 473 state = sw_http_09; |
476 break; | 474 break; |
477 default: | 475 default: |
478 return NGX_HTTP_PARSE_INVALID_REQUEST; | 476 return NGX_HTTP_PARSE_INVALID_REQUEST; |
479 } | 477 } |
480 break; | 478 break; |
481 | |
482 /* space+ after "http://host[:port] " */ | |
483 case sw_host_http_09: | |
484 switch (ch) { | |
485 case ' ': | |
486 break; | |
487 case CR: | |
488 r->http_minor = 9; | |
489 state = sw_almost_done; | |
490 break; | |
491 case LF: | |
492 r->http_minor = 9; | |
493 goto done; | |
494 case 'H': | |
495 r->http_protocol.data = p; | |
496 state = sw_http_H; | |
497 break; | |
498 default: | |
499 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
500 } | |
501 break; | |
502 | |
503 | 479 |
504 /* check "/.", "//", "%", and "\" (Win32) in URI */ | 480 /* check "/.", "//", "%", and "\" (Win32) in URI */ |
505 case sw_after_slash_in_uri: | 481 case sw_after_slash_in_uri: |
506 | 482 |
507 if (usual[ch >> 5] & (1U << (ch & 0x1f))) { | 483 if (usual[ch >> 5] & (1U << (ch & 0x1f))) { |
510 } | 486 } |
511 | 487 |
512 switch (ch) { | 488 switch (ch) { |
513 case ' ': | 489 case ' ': |
514 r->uri_end = p; | 490 r->uri_end = p; |
515 state = sw_check_uri_http_09; | 491 state = sw_http_09; |
516 break; | 492 break; |
517 case CR: | 493 case CR: |
518 r->uri_end = p; | 494 r->uri_end = p; |
519 r->http_minor = 9; | 495 r->http_minor = 9; |
520 state = sw_almost_done; | 496 state = sw_almost_done; |
582 case '.': | 558 case '.': |
583 r->uri_ext = p + 1; | 559 r->uri_ext = p + 1; |
584 break; | 560 break; |
585 case ' ': | 561 case ' ': |
586 r->uri_end = p; | 562 r->uri_end = p; |
587 state = sw_check_uri_http_09; | 563 state = sw_http_09; |
588 break; | 564 break; |
589 case CR: | 565 case CR: |
590 r->uri_end = p; | 566 r->uri_end = p; |
591 r->http_minor = 9; | 567 r->http_minor = 9; |
592 state = sw_almost_done; | 568 state = sw_almost_done; |
619 case '\0': | 595 case '\0': |
620 return NGX_HTTP_PARSE_INVALID_REQUEST; | 596 return NGX_HTTP_PARSE_INVALID_REQUEST; |
621 } | 597 } |
622 break; | 598 break; |
623 | 599 |
600 /* URI */ | |
601 case sw_uri: | |
602 | |
603 if (usual[ch >> 5] & (1U << (ch & 0x1f))) { | |
604 break; | |
605 } | |
606 | |
607 switch (ch) { | |
608 case ' ': | |
609 r->uri_end = p; | |
610 state = sw_http_09; | |
611 break; | |
612 case CR: | |
613 r->uri_end = p; | |
614 r->http_minor = 9; | |
615 state = sw_almost_done; | |
616 break; | |
617 case LF: | |
618 r->uri_end = p; | |
619 r->http_minor = 9; | |
620 goto done; | |
621 case '#': | |
622 r->complex_uri = 1; | |
623 break; | |
624 case '\0': | |
625 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
626 } | |
627 break; | |
628 | |
624 /* space+ after URI */ | 629 /* space+ after URI */ |
625 case sw_check_uri_http_09: | 630 case sw_http_09: |
626 switch (ch) { | 631 switch (ch) { |
627 case ' ': | 632 case ' ': |
628 break; | 633 break; |
629 case CR: | 634 case CR: |
630 r->http_minor = 9; | 635 r->http_minor = 9; |
636 case 'H': | 641 case 'H': |
637 r->http_protocol.data = p; | 642 r->http_protocol.data = p; |
638 state = sw_http_H; | 643 state = sw_http_H; |
639 break; | 644 break; |
640 default: | 645 default: |
641 r->space_in_uri = 1; | |
642 state = sw_check_uri; | |
643 p--; | |
644 break; | |
645 } | |
646 break; | |
647 | |
648 | |
649 /* URI */ | |
650 case sw_uri: | |
651 | |
652 if (usual[ch >> 5] & (1U << (ch & 0x1f))) { | |
653 break; | |
654 } | |
655 | |
656 switch (ch) { | |
657 case ' ': | |
658 r->uri_end = p; | |
659 state = sw_http_09; | |
660 break; | |
661 case CR: | |
662 r->uri_end = p; | |
663 r->http_minor = 9; | |
664 state = sw_almost_done; | |
665 break; | |
666 case LF: | |
667 r->uri_end = p; | |
668 r->http_minor = 9; | |
669 goto done; | |
670 case '#': | |
671 r->complex_uri = 1; | |
672 break; | |
673 case '\0': | |
674 return NGX_HTTP_PARSE_INVALID_REQUEST; | 646 return NGX_HTTP_PARSE_INVALID_REQUEST; |
675 } | |
676 break; | |
677 | |
678 /* space+ after URI */ | |
679 case sw_http_09: | |
680 switch (ch) { | |
681 case ' ': | |
682 break; | |
683 case CR: | |
684 r->http_minor = 9; | |
685 state = sw_almost_done; | |
686 break; | |
687 case LF: | |
688 r->http_minor = 9; | |
689 goto done; | |
690 case 'H': | |
691 r->http_protocol.data = p; | |
692 state = sw_http_H; | |
693 break; | |
694 default: | |
695 r->space_in_uri = 1; | |
696 state = sw_uri; | |
697 p--; | |
698 break; | |
699 } | 647 } |
700 break; | 648 break; |
701 | 649 |
702 case sw_http_H: | 650 case sw_http_H: |
703 switch (ch) { | 651 switch (ch) { |
1169 break; | 1117 break; |
1170 } | 1118 } |
1171 | 1119 |
1172 switch (ch) { | 1120 switch (ch) { |
1173 case ' ': | 1121 case ' ': |
1174 r->space_in_uri = 1; | 1122 return NGX_ERROR; |
1175 state = sw_check_uri; | |
1176 break; | |
1177 case '.': | 1123 case '.': |
1178 r->complex_uri = 1; | 1124 r->complex_uri = 1; |
1179 state = sw_uri; | 1125 state = sw_uri; |
1180 break; | 1126 break; |
1181 case '%': | 1127 case '%': |
1230 break; | 1176 break; |
1231 case '.': | 1177 case '.': |
1232 r->uri_ext = p + 1; | 1178 r->uri_ext = p + 1; |
1233 break; | 1179 break; |
1234 case ' ': | 1180 case ' ': |
1235 r->space_in_uri = 1; | 1181 return NGX_ERROR; |
1236 break; | |
1237 #if (NGX_WIN32) | 1182 #if (NGX_WIN32) |
1238 case '\\': | 1183 case '\\': |
1239 r->complex_uri = 1; | 1184 r->complex_uri = 1; |
1240 state = sw_after_slash_in_uri; | 1185 state = sw_after_slash_in_uri; |
1241 break; | 1186 break; |
1265 break; | 1210 break; |
1266 } | 1211 } |
1267 | 1212 |
1268 switch (ch) { | 1213 switch (ch) { |
1269 case ' ': | 1214 case ' ': |
1270 r->space_in_uri = 1; | 1215 return NGX_ERROR; |
1271 break; | |
1272 case '#': | 1216 case '#': |
1273 r->complex_uri = 1; | 1217 r->complex_uri = 1; |
1274 break; | 1218 break; |
1275 } | 1219 } |
1276 break; | 1220 break; |