Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 0 additions & 62 deletions proxy/hdrs/HTTP.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 == '%'));
}

/***********************************************************************
* *
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
2 changes: 0 additions & 2 deletions proxy/hdrs/HTTP.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include "ts/INK_MD5.h"
#include "MIME.h"
#include "URL.h"
#include "ts/TsBuffer.h"

#include "ts/ink_apidefs.h"

Expand Down Expand Up @@ -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);

Expand Down
74 changes: 72 additions & 2 deletions proxy/hdrs/URL.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -1279,6 +1306,7 @@ url_parse_internet(HdrHeap *heap, URLImpl *url, char const **start, char const *
*start = cur;
return PARSE_DONE;
}

/*-------------------------------------------------------------------------
-------------------------------------------------------------------------*/

Expand Down Expand Up @@ -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
2 changes: 2 additions & 0 deletions proxy/hdrs/URL.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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);
Expand Down