You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2022/12/12 18:20:25 UTC
[trafficserver] branch 9.1.x updated: Validate request-target (#9100)
This is an automated email from the ASF dual-hosted git repository.
bcall pushed a commit to branch 9.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/9.1.x by this push:
new e7549cbe3 Validate request-target (#9100)
e7549cbe3 is described below
commit e7549cbe3860d3d4ecc0f0e898c2a095bd0f141f
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 | 35 +++++++++++++++++++++++++++++++++++
proxy/hdrs/HTTP.h | 1 +
proxy/hdrs/unit_tests/test_Hdrs.cc | 4 +++-
3 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc
index 73cd16362..f3d4d469a 100644
--- a/proxy/hdrs/HTTP.cc
+++ b/proxy/hdrs/HTTP.cc
@@ -970,6 +970,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
}
@@ -1125,6 +1128,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
}
@@ -1134,6 +1140,35 @@ 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->m_len_host;
+ int path_len = url->m_len_path;
+ const char *path = url->m_ptr_path;
+ int scheme_len = url->m_len_scheme;
+
+ 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 83763c72d..a6738559b 100644
--- a/proxy/hdrs/HTTP.h
+++ b/proxy/hdrs/HTTP.h
@@ -441,6 +441,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 e7314fee3..2aad37de2 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},
}};