Solving DOM XSS Puzzles

Original Post:
Solving DOM XSS Puzzles
We discussed this vulnerability during Episode 117 on 07 February 2022

We’ve got two XSS “puzzles” in unnamed bounty programs, each with somewhat interesting exploit strategies. The original post is worth a read for more insight into the thought process leading to the discovery of each step.

Puzzle 1

The first puzzle started off with a postMessage handler that did not perform any origin checking. It could be used to set the windows.settingsSync value when the event’s type was ChatSettings. In turn, the settingsSync values were used by some third-party code. Specifically it could be triggered to make what seems like a “refresh settings” sort of request. It would figure out the subdomain for the user’s region, POST to it, use the response as the windows.settingsSync then load a JS file based on the window.settingsSync.versionNumber from cloudfront, and then it would use window.settingsSync.config in an eval(...).

The region domain was based on the window.settingsSync.region so by using the first postMessage issue to change the region to a malicious value, they could have a domain that resolves somewhere attacker controlled. Allowing arbitrary Javascript to be passed into eval. Unfortunately, this was in the context of cloudfront and not the original application.

However the original application did have another postMessage handler, this handler did origin checking, and would trust the cloudfront domain. It would await the IframeLoaded event and then send back a “credentialConfig” which would include sensitive information like the user’s session token, enabling account hijacking.

Puzzle Two

The second puzzle starts off with a bit of a weird oauth setup. The application ones you landed on the company path, it would make a GET request to oauth.company.com/oauth_data?client_id=.... The returned page contained some of the standard oauth provider data like logourl, name, link. Of interest was the introdunction field which would be directly injected in the page. Enabling XSS if an attacker could control the results.

Of course, an attacker could control the results because the domain used for this GET request was taken from the URL of the original page, the domain query parameter. Unfortunately for the author the page’s Content-Security-Policy (CSP) prevented arbitary page loaded, but did allow the company’s site and *.amazonaws.com. Which is the root domain for a lot of AWS content, like S3 buckets. So an attacker could just host their attack on S3.

There was a second CSP issue, script-src was set to self or *.company.com. To get around this restriction, they utilized an open redirect on the company site. The site would ensure that the provided URL ended with comapny.com the problem was that it allowed new-line characters, which browsers would treat a bit differently. By including a url encoded new-line character (%0a) in the subdomain, the browser would send the request off the to domain before the newline and the newline and the rest would be part of the path. Resulting again in XSS.