The user may be subjected to phishing attacks by being redirected to an untrusted and attacker controlled web page that appears to be a trusted web site. The phishers may then steal the user’s credentials and then use these credentials to access the legitimate web site. Because the server name in the modified link is identical to the original site, phishing attempts have a more trustworthy appearance.

Proof Of Concept :

>>> x = urlparse("////evil.com")

///evil.com will be parsed as relative-path URL which is the correct expected behaviour

>>> print x

>>> ParseResult(scheme=", netloc=", path=’//evil.com’, params=", query=", fragment=")

As you see two slashes are removed and it is marked as a relative-path URL but when we reconstruct the URL using urlunparse() function, the URL is treated as an absolute path.

>>> x = urlunparse(urlparse("////evil.com"))

>>> urlparse(x)

ParseResult(scheme=", netloc=’evil.com’, path=", params=", query=", fragment=")

This vulnerability can be practically exploited this way : https://www.example.com/login?next=////evil.com

Mitigation :

This can be mitigated by checking if the path starts with double slashes and the URL encoding the two leading double slashes. Otherwise, it is recommanded to not use urlunparse(urlparse(url)) to validate a url.

References:

https://docs.python.org/2/library/urlparse.html

https://bugs.python.org/issue23505

https://github.com/reddit/reddit/commit/689a9554e60c6e403528b5d62a072ac4a072a20e

Greetz : Thanks to Reddit.com security team for their precious collaboration and help.

{: .text-justify}