diff --git a/src/XrdHttp/XrdHttpReq.cc b/src/XrdHttp/XrdHttpReq.cc index 5728368e3b4..91459a398b9 100644 --- a/src/XrdHttp/XrdHttpReq.cc +++ b/src/XrdHttp/XrdHttpReq.cc @@ -883,15 +883,47 @@ void XrdHttpReq::appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, } -// Extracts the opaque info from the given url +// Sanitize the resource from the http[s]://[host]/ questionable prefix +// https://github.com/xrootd/xrootd/issues/1675 +void XrdHttpReq::sanitizeResourcePfx() { + + if (resource.beginswith("https://")) { + // Find the slash that follows the hostname, and keep it + int p = resource.find('/', 8); + resource.erasefromstart(p); + return; + } + + if (resource.beginswith("http://")) { + // Find the slash that follows the hostname, and keep it + int p = resource.find('/', 7); + resource.erasefromstart(p); + return; + } +} + + +// Parse a resource line: +// - sanitize +// - extracts the opaque info from the given url +// - sanitize the resource from http[s]://[host]/ questionable prefix void XrdHttpReq::parseResource(char *res) { + + + + // Look for the first '?' char *p = strchr(res, '?'); // Not found, then it's just a filename if (!p) { resource.assign(res, 0); + + // Some poor client implementations may inject a http[s]://[host]/ prefix + // to the resource string. Here we choose to ignore it as a protection measure + sanitizeResourcePfx(); + char *buf = unquote((char *)resource.c_str()); resource.assign(buf, 0); resourceplusopaque.assign(buf, 0); @@ -912,7 +944,11 @@ void XrdHttpReq::parseResource(char *res) { int cnt = p - res; // Number of chars to copy resource.assign(res, 0, cnt - 1); - + + // Some poor client implementations may inject a http[s]://[host]/ prefix + // to the resource string. Here we choose to ignore it as a protection measure + sanitizeResourcePfx(); + char *buf = unquote((char *)resource.c_str()); resource.assign(buf, 0); free(buf); diff --git a/src/XrdHttp/XrdHttpReq.hh b/src/XrdHttp/XrdHttpReq.hh index 4d470d2a444..5cbb81ea57a 100644 --- a/src/XrdHttp/XrdHttpReq.hh +++ b/src/XrdHttp/XrdHttpReq.hh @@ -113,6 +113,9 @@ private: void parseResource(char *url); // Map an XRootD error code to an appropriate HTTP status code and message void mapXrdErrorToHttpStatus(); + + // Sanitize the resource from http[s]://[host]/ questionable prefix + void sanitizeResourcePfx(); public: XrdHttpReq(XrdHttpProtocol *protinstance) : keepalive(true) {