Add userinfo characters check.
This commit is contained in:
parent
47fd88b33f
commit
e2d079860d
@ -11,6 +11,7 @@
|
|||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
#include "td/utils/Parser.h"
|
#include "td/utils/Parser.h"
|
||||||
#include "td/utils/port/IPAddress.h"
|
#include "td/utils/port/IPAddress.h"
|
||||||
|
#include "td/utils/SliceBuilder.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -138,42 +139,50 @@ Result<HttpUrl> parse_url(Slice url, HttpUrl::Protocol default_protocol) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto check_url_part = [](Slice part, Slice name, bool allow_colon) {
|
||||||
|
for (size_t i = 0; i < part.size(); i++) {
|
||||||
|
char c = part[i];
|
||||||
|
if (is_alnum(c) || c == '.' || c == '-' || c == '_' || c == '!' || c == '$' || c == ',' || c == '~' || c == '*' ||
|
||||||
|
c == '\'' || c == '(' || c == ')' || c == ';' || c == '&' || c == '+' || c == '=' ||
|
||||||
|
(allow_colon && c == ':')) {
|
||||||
|
// symbols allowed by RFC 7230 and RFC 3986
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == '%') {
|
||||||
|
c = part[++i];
|
||||||
|
if (is_hex_digit(c)) {
|
||||||
|
c = part[++i];
|
||||||
|
if (is_hex_digit(c)) {
|
||||||
|
// percent encoded symbol as allowed by RFC 7230 and RFC 3986
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Status::Error(PSLICE() << "Wrong percent-encoded symbol in URL " << name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// all other symbols aren't allowed
|
||||||
|
auto uc = static_cast<unsigned char>(c);
|
||||||
|
if (uc >= 128) {
|
||||||
|
// but we allow plain UTF-8 symbols
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return Status::Error(PSLICE() << "Disallowed character in URL " << name);
|
||||||
|
}
|
||||||
|
return Status::OK();
|
||||||
|
};
|
||||||
|
|
||||||
string host_str = to_lower(host);
|
string host_str = to_lower(host);
|
||||||
for (size_t i = 0; i < host_str.size(); i++) {
|
if (is_ipv6) {
|
||||||
char c = host_str[i];
|
for (size_t i = 1; i + 1 < host_str.size(); i++) {
|
||||||
if (is_ipv6) {
|
char c = host_str[i];
|
||||||
if (i == 0 || i + 1 == host_str.size() || c == ':' || ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||
|
if (c == ':' || ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || c == '.') {
|
||||||
c == '.') {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Status::Error("Wrong IPv6 URL host");
|
return Status::Error("Wrong IPv6 URL host");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (('a' <= c && c <= 'z') || c == '.' || ('0' <= c && c <= '9') || c == '-' || c == '_' || c == '!' || c == '$' ||
|
TRY_STATUS(check_url_part(host_str, "host", false));
|
||||||
c == ',' || c == '~' || c == '*' || c == '\'' || c == '(' || c == ')' || c == ';' || c == '&' || c == '+' ||
|
TRY_STATUS(check_url_part(userinfo, "userinfo", true));
|
||||||
c == '=') {
|
|
||||||
// symbols allowed by RFC 7230 and RFC 3986
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == '%') {
|
|
||||||
c = host_str[++i];
|
|
||||||
if (('a' <= c && c <= 'f') || ('0' <= c && c <= '9')) {
|
|
||||||
c = host_str[++i];
|
|
||||||
if (('a' <= c && c <= 'f') || ('0' <= c && c <= '9')) {
|
|
||||||
// percent encoded symbol as allowed by RFC 7230 and RFC 3986
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Status::Error("Wrong percent-encoded symbol in URL host");
|
|
||||||
}
|
|
||||||
|
|
||||||
// all other symbols aren't allowed
|
|
||||||
auto uc = static_cast<unsigned char>(c);
|
|
||||||
if (uc >= 128) {
|
|
||||||
// but we allow plain UTF-8 symbols
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return Status::Error("Wrong URL host");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return HttpUrl{protocol, userinfo.str(), std::move(host_str), is_ipv6, specified_port, port, std::move(query_str)};
|
return HttpUrl{protocol, userinfo.str(), std::move(host_str), is_ipv6, specified_port, port, std::move(query_str)};
|
||||||
|
Loading…
Reference in New Issue
Block a user