

Hackers: can you impersonate other users using javascript? - EGreg

I've been thinking about authentication with third-party services lately. You know how a website uses facebook connect to authenticate a user? Well, what is to prevent you from going into the javascript and searching for your uid and changing it to e.g. #4, mark zuckerberg, or that of Mike Arrington, before posting something to the server?<p>Is there protection against this on the websites?<p>Today, I fooled around with DISQUS and used the javascript console to try and fool it into thinking I was someone else. But I think that with DISQUS, they rely on the cookie (not the uid in javascript) when you post the comment, so you can't impersonate other users. However, if we go back to my original question -- how do websites which implement authentication with facebook, google, etc. protect against such impersonations?
======
Mithrandir
<https://github.com/codebutler/firesheep>

~~~
EGreg
no no, I don't mean stealing someone's cookie through some kind of Man-In-The-
Middle attack.

I mean impersonating someone else simply by logging in and then changing some
javascript variables before posting to the server.

~~~
maushu
If the service is well implemented this should be very hard. Basically when
you login you receive a session/ticket (usually by cookie), using that session
you post as yourself.

To post as somebody else you would need to get their session which is
difficult since it expires after some time and it should very hard to guess
(usually an hash with 32 characters or more).

What firesheep does is steal those sessions during transaction. No guessing
there.

~~~
EGreg
fine, but if I am making a third-party authentication service, how do I
prevent the users of that service from being bamboozled by simple javascript?
How does facebook prevent a website from being bamboozled?

Is there any technique that facebook can recommend (such as signing the uid
and sending the signature along with the id on all server requests) so that
the website isn't fooled?

~~~
Swannie
I'm not sure I understand your question.

If you mean: I have an authentication service, Auth.com, and I would like the
users to be able to enter their user name and password on AnotherSite.com, how
do I stop javascript on AnotherSite.com hijacking their submission to
Auth.com?

Then the short answer is, you can't. That is why all services redirect you to
their own login page, where they control the HTML (and can audit to be sure
that no one has injected code into their site).

What Facebook does is usually in an iFrame, which accesses the user
information relatively securely. Any interaction more complex than a "like" is
generally redirected via facebook.com (e.g. any permission grants). iFrame's
used to be riddled with flaws, but I believe they are considered fairly safe
these days.

Go educate yourself on the protection of XSS and CSRF/XSRF, and you'll be able
to answer all of your own questions.

~~~
EGreg
No, that's not what I am asking. And I am very familiar with how to combat XSS
and CSRF, having written a PHP framework that does it for you out of the box,
among other things (<http://phponpie.com>)

I am asking another question.

If I am operating an OpenID provider, say Auth.com, and CoolStuff.com uses me
to authenticate a user, then they can use that session. Great. But now let's
say I operate an OAuth provider, and it releases this user's uid, first_name
and last_name. What measures does facebook and other OAuth providers take to
prevent the uid, first_name, last_name and other data from just being changed
by the user in javascript, before being posted to the CoolStuff.com servers,
after they have been obtained using Javascript ... such as FB.api('fql.query',
...)

~~~
kertap
If I understand the question correctly, you are asking what's to stop someone
from changing the UID, etc when the user is redirected from auth.com to
coolstuff.com?

From my understanding of OAuth, when the uid, first_name and last_name are
sent by auth.com it also sends a cryptographic hash of everything. So if you
change the uid, you would also have to change the hash and you can't change
the hash without knowing the shared secret that the auth.com and coolstuff.com
have decided on prior to your request.

~~~
EGreg
so what you are saying is that coolstuff.com's servers must always look for a
signature from auth.com when they are accepting user data, they cannot trust
the user input. That makes sense. So does facebook connect, google, etc. have
this? I assume not.

~~~
Swannie
Well if you protect against CSRF you should be checking a nonce for all form
submissions anyway. This doesn't appear to be all that different to me.

I'm intrigued now, I hope someone can give details!

~~~
sawyer
OAuth 2.0 login providers use an access token that is user specific for all
subsequent interaction.

For example, with Facebook, once a user has logged in and given Application X
permission to access their details, FB will send the user's id, name, etc.
(whatever data the user has granted access to) along with a unique access
token. The next time, and every subsequent time Application X wants to access
the FB API on the user's behalf it is required to send that access token. From
javascript you might be able to change the token, however, Application X's
next interaction with the FB API will fail if the token is invalid and there
is no way to derive a token value from a FB user's id.

~~~
EGreg
That's it? That sucks.

I don't have to change the token. I just have to change the data given by
facebook (including the uid) before the website's dumb javascript uses it in a
post back to the server. Since it's not signed by Facebook, how can the
website's server trust the uid? Never trust your user input.

~~~
sawyer
The user logs in on Facebook's server, there is no opportunity to change a
uid. Facebook might return the logged in user's id, however that's not useful,
the only way to interact with their API will be with the access token (which
only grants you access to the logged in user's scope).

~~~
EGreg
I am not talking about interacting with their API.

Facebook returns a uid. When the user takes an action, this uid is sent to the
server. The server trusts the uid, and saves this action as taken by the user
identified by this uid.

And let's say it's not the uid. Let's say it's the user's name.

It trusts the user input basically. But it should probably be getting it
directly from facebook, or in a signed structure, right?

