You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2015/12/18 23:37:35 UTC
trafficserver git commit: TS-4043: Prevent bogus FQDN characters in
host header This close #356.
Repository: trafficserver
Updated Branches:
refs/heads/master d64434ea0 -> ada9752e7
TS-4043: Prevent bogus FQDN characters in host header
This close #356.
Validate the host header string to prevent malformed hostnames from being let in.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ada9752e
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ada9752e
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ada9752e
Branch: refs/heads/master
Commit: ada9752e7224abc7f8a231d57d32f84163726b3c
Parents: d64434e
Author: Daniel Xu <dl...@yahoo.com>
Authored: Mon Nov 23 20:35:41 2015 +0000
Committer: Alan M. Carroll <am...@apache.org>
Committed: Fri Dec 18 16:36:48 2015 -0600
----------------------------------------------------------------------
proxy/hdrs/HTTP.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++++--
proxy/hdrs/HTTP.h | 2 ++
2 files changed, 68 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ada9752e/proxy/hdrs/HTTP.cc
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc
index 46bc135..2e852fd 100644
--- a/proxy/hdrs/HTTP.cc
+++ b/proxy/hdrs/HTTP.cc
@@ -23,7 +23,6 @@
#include "ts/ink_defs.h"
#include "ts/ink_platform.h"
-#include "ts/TsBuffer.h"
#include "ts/ink_inet.h"
#include <assert.h>
#include <stdio.h>
@@ -161,6 +160,15 @@ is_digit(char c)
return ((c <= '9') && (c >= '0'));
}
+// test to see if a character is a valid character for a host in a URI according to
+// RFC 3986 and RFC 1034
+inline static int
+is_host_char(char c)
+{
+ return (ParseRules::is_alnum(c) || (c == '-') || (c == '.') || (c == '[') || (c == ']') || (c == '_') || (c == ':') ||
+ (c == '~') || (c == '%'));
+}
+
/***********************************************************************
* *
* M A I N C O D E *
@@ -1107,6 +1115,18 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const
return mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof);
}
+// Checks if `addr` is a valid FQDN string
+bool
+validate_host_name(ts::ConstBuffer addr)
+{
+ while (addr) {
+ if (!(is_host_char(*addr)))
+ return false;
+ ++addr;
+ }
+ return true;
+}
+
MIMEParseResult
validate_hdr_host(HTTPHdrImpl *hh)
{
@@ -1124,9 +1144,11 @@ validate_hdr_host(HTTPHdrImpl *hh)
if (port.size() > 5)
return PARSE_ERROR;
int port_i = ink_atoi(port.data(), port.size());
- if (port.size() > 5 || port_i >= 65536 || port_i <= 0)
+ if (port_i >= 65536 || port_i <= 0)
return PARSE_ERROR;
}
+ if (!validate_host_name(addr))
+ return PARSE_ERROR;
while (rest && PARSE_DONE == ret) {
if (!ParseRules::is_ws(*rest))
return PARSE_ERROR;
@@ -2188,3 +2210,45 @@ HTTPInfo::push_frag_offset(FragOffset offset)
m_alt->m_frag_offsets[m_alt->m_frag_offset_count++] = offset;
}
+
+
+/*-------------------------------------------------------------------------
+ * Regression tests
+ -------------------------------------------------------------------------*/
+#if TS_HAS_TESTS
+#include "ts/TestBox.h"
+
+const static struct {
+ const char *const text;
+ bool valid;
+} http_validate_hdr_field_test_case[] = {{"yahoo", true},
+ {"yahoo.com", true},
+ {"yahoo.wow.com", true},
+ {"yahoo.wow.much.amaze.com", true},
+ {"209.131.52.50", true},
+ {"192.168.0.1", true},
+ {"localhost", true},
+ {"3ffe:1900:4545:3:200:f8ff:fe21:67cf", true},
+ {"fe80:0:0:0:200:f8ff:fe21:67cf", true},
+ {"fe80::200:f8ff:fe21:67cf", true},
+ {"<svg onload=alert(1)>", false}, // Sample host header XSS attack
+ {"jlads;f8-9349*(D&F*D(234jD*(FSD*(VKLJ#(*$@()#$)))))", false},
+ {"\"\t\n", false},
+ {"!@#$%^ &*(*&^%$#@#$%^&*(*&^%$#))", false},
+ {":):(:O!!!!!!", false}};
+
+REGRESSION_TEST(VALIDATE_HDR_FIELD)(RegressionTest *t, int /* level ATS_UNUSED */, int *pstatus)
+{
+ TestBox box(t, pstatus);
+ box = REGRESSION_TEST_PASSED;
+
+ for (unsigned int i = 0; i < sizeof(http_validate_hdr_field_test_case) / sizeof(http_validate_hdr_field_test_case[0]); ++i) {
+ const char *const txt = http_validate_hdr_field_test_case[i].text;
+ ts::ConstBuffer tmp = ts::ConstBuffer(txt, strlen(txt));
+ box.check(validate_host_name(tmp) == http_validate_hdr_field_test_case[i].valid,
+ "Validation of FQDN (host) header: \"%s\", expected %s, but not", txt,
+ (http_validate_hdr_field_test_case[i].valid ? "true" : "false"));
+ }
+}
+
+#endif // TS_HAS_TESTS
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ada9752e/proxy/hdrs/HTTP.h
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h
index 7d91687..de8499f 100644
--- a/proxy/hdrs/HTTP.h
+++ b/proxy/hdrs/HTTP.h
@@ -29,6 +29,7 @@
#include "ts/INK_MD5.h"
#include "MIME.h"
#include "URL.h"
+#include "ts/TsBuffer.h"
#include "ts/ink_apidefs.h"
@@ -454,6 +455,7 @@ void http_parser_clear(HTTPParser *parser);
MIMEParseResult http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const char **start, const char *end,
bool must_copy_strings, bool eof);
MIMEParseResult validate_hdr_host(HTTPHdrImpl *hh);
+bool validate_host_name(ts::ConstBuffer addr);
MIMEParseResult http_parser_parse_resp(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const char **start, const char *end,
bool must_copy_strings, bool eof);