mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-26 12:24:46 +00:00
Reject userinfo and backslashes in a URL authority
parse_url took http://user@evil.com/ for the host "user@evil.com", where parsers that honour userinfo, or read a backslash as '/', see evil.com. userinfo is not supported, so reject both.
This commit is contained in:
1 parent
eeaae4bc3c
commit
aaccde2122
2 files changed
+14
-5
No files matched your search
@@ -889,6 +889,12 @@ inline bool parse_url(const std::string &url, UrlComponents &uc) {
|
|||||||
auto has_authority = has_authority_prefix || (!url.empty() && url[0] != '/' &&
|
auto has_authority = has_authority_prefix || (!url.empty() && url[0] != '/' &&
|
||||||
url[0] != '?' && url[0] != '#');
|
url[0] != '?' && url[0] != '#');
|
||||||
if (has_authority) {
|
if (has_authority) {
|
||||||
|
// userinfo is not supported, and a backslash that some parsers take for
|
||||||
|
// '/' would leave them seeing another host than this one.
|
||||||
|
if (url.find_first_of("@\\", pos) < url.find_first_of("/?#", pos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (pos < url.size() && url[pos] == '[') {
|
if (pos < url.size() && url[pos] == '[') {
|
||||||
auto close = url.find(']', pos);
|
auto close = url.find(']', pos);
|
||||||
if (close == std::string::npos) { return false; }
|
if (close == std::string::npos) { return false; }
|
||||||
|
|||||||
+8
-5
@@ -19498,11 +19498,14 @@ TEST(ParseUrlTest, FragmentHandling) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(ParseUrlTest, UserinfoHandling) {
|
TEST(ParseUrlTest, UserinfoHandling) {
|
||||||
// Userinfo with @ but no colon — host includes @
|
// userinfo is not supported. Parsers that honour it, or take a backslash for
|
||||||
detail::UrlComponents uc;
|
// '/', would see evil.com where the host used to be the whole authority.
|
||||||
ASSERT_TRUE(detail::parse_url("http://user@host.com/path", uc));
|
const char *urls[] = {"http://user@evil.com/", "http://user:pass@evil.com/",
|
||||||
EXPECT_EQ("user@host.com", uc.host);
|
"http://evil.com\\@good.com/", "//user@evil.com/x"};
|
||||||
EXPECT_EQ("/path", uc.path);
|
for (auto url : urls) {
|
||||||
|
detail::UrlComponents uc;
|
||||||
|
EXPECT_FALSE(detail::parse_url(url, uc)) << url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ParseUrlTest, IPv6EdgeCases) {
|
TEST(ParseUrlTest, IPv6EdgeCases) {
|
||||||
|
|||||||
Reference in new issue
Block a user