You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2022/12/14 23:27:50 UTC
[trafficserver] branch 9.2.x updated: Validate request-target (#9100)
This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 9.2.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/9.2.x by this push:
new 6fb210ff7 Validate request-target (#9100)
6fb210ff7 is described below
commit 6fb210ff76f5ea746e74375f1880dac830fedfa1
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Wed Sep 21 08:04:47 2022 +0900
Validate request-target (#9100)
(cherry picked from commit 3b9cbf873a77bb7f9297f2b16496a290e0cf7de1)
---
proxy/hdrs/HTTP.cc | 37 +++++++++++++++++++++++++++++++++++++
proxy/hdrs/HTTP.h | 1 +
proxy/hdrs/unit_tests/test_Hdrs.cc | 4 +++-
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc
index 4e17d542f..ccaf8ca42 100644
--- a/proxy/hdrs/HTTP.cc
+++ b/proxy/hdrs/HTTP.cc
@@ -974,6 +974,9 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const
ParseResult ret = mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof,
false, max_hdr_field_size);
// If we're done with the main parse do some validation
+ if (ret == PARSE_RESULT_DONE) {
+ ret = validate_hdr_request_target(HTTP_WKSIDX_GET, url);
+ }
if (ret == PARSE_RESULT_DONE) {
ret = validate_hdr_host(hh); // check HOST header
}
@@ -1129,6 +1132,9 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const
ParseResult ret = mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, false,
max_hdr_field_size);
// If we're done with the main parse do some validation
+ if (ret == PARSE_RESULT_DONE) {
+ ret = validate_hdr_request_target(hh->u.req.m_method_wks_idx, hh->u.req.m_url_impl);
+ }
if (ret == PARSE_RESULT_DONE) {
ret = validate_hdr_host(hh); // check HOST header
}
@@ -1138,6 +1144,37 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const
return ret;
}
+ParseResult
+validate_hdr_request_target(int method_wk_idx, URLImpl *url)
+{
+ ParseResult ret = PARSE_RESULT_DONE;
+ int host_len;
+ url->get_host(&host_len);
+ int path_len;
+ const char *path = url->get_path(&path_len);
+ int scheme_len;
+ url->get_scheme(&scheme_len);
+
+ if (host_len == 0) {
+ if (path_len == 1 && path[0] == '*') { // asterisk-form
+ // Skip this check for now because URLImpl can't distinguish '*' and '/*'
+ // if (method_wk_idx != HTTP_WKSIDX_OPTIONS) {
+ // ret = PARSE_RESULT_ERROR;
+ // }
+ } else { // origin-form
+ // Nothing to check here
+ }
+ } else if (scheme_len == 0 && host_len != 0) { // authority-form
+ if (method_wk_idx != HTTP_WKSIDX_CONNECT) {
+ ret = PARSE_RESULT_ERROR;
+ }
+ } else { // absolute-form
+ // Nothing to check here
+ }
+
+ return ret;
+}
+
ParseResult
validate_hdr_host(HTTPHdrImpl *hh)
{
diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h
index 6d01fb2e1..710fbaf00 100644
--- a/proxy/hdrs/HTTP.h
+++ b/proxy/hdrs/HTTP.h
@@ -445,6 +445,7 @@ void http_parser_clear(HTTPParser *parser);
ParseResult http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const char **start, const char *end,
bool must_copy_strings, bool eof, int strict_uri_parsing, size_t max_request_line_size,
size_t max_hdr_field_size);
+ParseResult validate_hdr_request_target(int method_wks_idx, URLImpl *url);
ParseResult validate_hdr_host(HTTPHdrImpl *hh);
ParseResult validate_hdr_content_length(HdrHeap *heap, HTTPHdrImpl *hh);
ParseResult http_parser_parse_resp(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const char **start, const char *end,
diff --git a/proxy/hdrs/unit_tests/test_Hdrs.cc b/proxy/hdrs/unit_tests/test_Hdrs.cc
index 73022bf62..30b9b198e 100644
--- a/proxy/hdrs/unit_tests/test_Hdrs.cc
+++ b/proxy/hdrs/unit_tests/test_Hdrs.cc
@@ -45,7 +45,7 @@ TEST_CASE("HdrTestHttpParse", "[proxy][hdrtest]")
int expected_result;
int expected_bytes_consumed;
};
- static const std::array<Test, 21> tests = {{
+ static const std::array<Test, 23> tests = {{
{"GET /index.html HTTP/1.0\r\n", PARSE_RESULT_DONE, 26},
{"GET /index.html HTTP/1.0\r\n\r\n***BODY****", PARSE_RESULT_DONE, 28},
{"GET /index.html HTTP/1.0\r\nUser-Agent: foobar\r\n\r\n***BODY****", PARSE_RESULT_DONE, 48},
@@ -66,6 +66,8 @@ TEST_CASE("HdrTestHttpParse", "[proxy][hdrtest]")
{"GET /index.html HTTP/1.0\r\nUser-Agent: foobar\r\n", PARSE_RESULT_DONE, 46},
{"GET /index.html HTTP/1.0\r\n", PARSE_RESULT_DONE, 26},
{"GET /index.html hTTP/1.0\r\n", PARSE_RESULT_ERROR, 26},
+ {"CONNECT foo.example HTTP/1.1\r\n", PARSE_RESULT_DONE, 30},
+ {"GET foo.example HTTP/1.1\r\n", PARSE_RESULT_ERROR, 26},
{"", PARSE_RESULT_ERROR, 0},
}};