Repository: trafficserver
Updated Branches:
  refs/heads/master 67cc19efe -> 46edfde61


TS-4143: Validate host in GET URL
This close #430.

Also moved all the host validation logic to URL.cc since HTTP.cc
inherits from URL.cc.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/46edfde6
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/46edfde6
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/46edfde6

Branch: refs/heads/master
Commit: 46edfde6177ad8cc2f3a4ab273800b5385720514
Parents: 67cc19e
Author: Daniel Xu <[email protected]>
Authored: Fri Jan 22 16:37:55 2016 +0000
Committer: Alan M. Carroll <[email protected]>
Committed: Fri Jan 22 16:04:09 2016 -0600

----------------------------------------------------------------------
 proxy/hdrs/HTTP.cc | 62 -----------------------------------------
 proxy/hdrs/HTTP.h  |  2 --
 proxy/hdrs/URL.cc  | 74 +++++++++++++++++++++++++++++++++++++++++++++++--
 proxy/hdrs/URL.h   |  2 ++
 4 files changed, 74 insertions(+), 66 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/46edfde6/proxy/hdrs/HTTP.cc
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc
index 2e852fd..f0447d5 100644
--- a/proxy/hdrs/HTTP.cc
+++ b/proxy/hdrs/HTTP.cc
@@ -160,14 +160,6 @@ 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 == '%'));
-}
 
 /***********************************************************************
  *                                                                     *
@@ -1115,18 +1107,6 @@ 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)
 {
@@ -2210,45 +2190,3 @@ 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/46edfde6/proxy/hdrs/HTTP.h
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h
index de8499f..7d91687 100644
--- a/proxy/hdrs/HTTP.h
+++ b/proxy/hdrs/HTTP.h
@@ -29,7 +29,6 @@
 #include "ts/INK_MD5.h"
 #include "MIME.h"
 #include "URL.h"
-#include "ts/TsBuffer.h"
 
 #include "ts/ink_apidefs.h"
 
@@ -455,7 +454,6 @@ 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);
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/46edfde6/proxy/hdrs/URL.cc
----------------------------------------------------------------------
diff --git a/proxy/hdrs/URL.cc b/proxy/hdrs/URL.cc
index 2eb4181..f5de83f 100644
--- a/proxy/hdrs/URL.cc
+++ b/proxy/hdrs/URL.cc
@@ -98,6 +98,29 @@ int URL_LEN_MMST;
 // url_MD5_get_fast() does NOT produce the same result as 
url_MD5_get_general().
 static int url_hash_method = 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 == '%'));
+}
+
+
+// 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;
+}
+
+
 /*-------------------------------------------------------------------------
   -------------------------------------------------------------------------*/
 URLHashContext::HashType URLHashContext::Setting = URLHashContext::MD5;
@@ -1264,8 +1287,12 @@ url_parse_internet(HdrHeap *heap, URLImpl *url, char 
const **start, char const *
       last_colon = 0; // prevent port setting.
     }
   }
-  if (host._size)
-    url_host_set(heap, url, host._ptr, host._size, copy_strings_p);
+  if (host._size) {
+    if (validate_host_name(host))
+      url_host_set(heap, url, host._ptr, host._size, copy_strings_p);
+    else
+      return PARSE_ERROR;
+  }
 
   if (last_colon) {
     ink_assert(n_colon);
@@ -1279,6 +1306,7 @@ url_parse_internet(HdrHeap *heap, URLImpl *url, char 
const **start, char const *
   *start = cur;
   return PARSE_DONE;
 }
+
 /*-------------------------------------------------------------------------
   -------------------------------------------------------------------------*/
 
@@ -1735,3 +1763,45 @@ url_host_MD5_get(URLImpl *url, INK_MD5 *md5)
   ctx.update(&port, sizeof(port));
   ctx.finalize(*md5);
 }
+
+
+/*-------------------------------------------------------------------------
+ * 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/46edfde6/proxy/hdrs/URL.h
----------------------------------------------------------------------
diff --git a/proxy/hdrs/URL.h b/proxy/hdrs/URL.h
index d56b170..5982635 100644
--- a/proxy/hdrs/URL.h
+++ b/proxy/hdrs/URL.h
@@ -30,6 +30,7 @@
 #include "ts/INK_MD5.h"
 #include "ts/MMH.h"
 #include "MIME.h"
+#include "ts/TsBuffer.h"
 
 #include "ts/ink_apidefs.h"
 
@@ -193,6 +194,7 @@ extern int URL_LEN_MMST;
 void url_adjust(MarshalXlate *str_xlate, int num_xlate);
 
 /* Public */
+bool validate_host_name(ts::ConstBuffer addr);
 void url_init();
 
 URLImpl *url_create(HdrHeap *heap);

Reply via email to