Forum Moderators: phranque

Message Too Old, No Replies

FF allows users to alter cookie data

alert on possible security issue

         

csdude55

12:11 pm on Apr 11, 2019 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I rarely use Firefox other than for general testing, because Chrome is almost always faster for me. I never use it for debugging.

Yesterday, though, someone alerted me to a security issue with FF. It was a minor issue on my end and easily fixed, but I wanted to mention it since it could be a major issue for others.

Apparently there's an option to see what cookies a site stores for you, and the user can easily change the content of those cookie.

On my end, I have a few scripts that run on every page so that, after a user has logged in, it would show "welcome csdude55" and how many Private Messages they've gotten. To do this in PHP, I would simply do something like:

if ($_COOKIE['user'] && $_COOKIE['pass']) {
$welcome = 'welcome ' . $_COOKIE['user'];

$sth_user = sprintf("SELECT COUNT(1) FROM pm WHERE username = '%s'",
mysql_real_escape_string($_COOKIE['user']));

list($counter) = mysql_fetch_row(mysql_query($sth_user));

$welcome_count = 'You have mail: Inbox ' . $counter;
}

(That's not the exact code, of course, I just typed it up for the example)

So nothing sensitive, just reiterating the username and how many messages they've gotten. But since the user could change the contents of the cookie on their end, a cracker would be able to change their own cookie to the username of any other user and:

1. emulate the page to show their username, making others think that they had hacked their account; and

2. see how many messages that person had gotten.

The quick resolution on my end was to run a MySQL query on each page to make sure the cookie data matched what's on file. But that makes every page run marginally slower, so that's not great.

A long term solution might be to store encrypted data in the cookie, making it harder for the cracker to modify the cookie like that. In my case, since changing the cookie wouldn't reveal anything sensitive, then that will probably be OK.

But for anyone else that uses a cookie to show information, I thought that they should be aware of this issue. For all I know, this option has existed for years and I just didn't know it... but if I didn't know it then there's a good chance that someone else didn't know it, either.

graeme_p

12:37 pm on Apr 11, 2019 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The server should never trust the client. There are lots of other ways to do this.

Its generally a bad idea to write your own authentication. Use a library or framework. There are too many places you can make a non-obvious mistake.

What you should be doing here is something like using signed sessions tied in the back end to a user, or at least adding a signature cookie (e.g. a salted hash) to check the username is not a fake. Its not difficult to implement, but it is difficult to test and review.

Why do you have a password cookie? You only need the password at login, to compare against the (hopefully hashed) value in your DB.

topr8

12:54 pm on Apr 11, 2019 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



this isn't a firefox issue!

there are plenty of plugins for chrome which enable you to easily change cookie values too.

although i agree with graeme_p

csdude55

3:25 pm on Apr 11, 2019 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I originally wrote this in 2004 or 2005, and it wasn't an issue back then. After several rebuilds I've never changed the format, with the logic of "if it ain't broke, don't fix it". I had no idea that it was that simple to change the content of the cookie now.

What you should be doing here is something like using signed sessions tied in the back end to a user, or at least adding a signature cookie (e.g. a salted hash) to check the username is not a fake.

But either way I would still have to run a query to compare the stored hash to the database to get the actual username, right? If that's the case then I'm not sure if it's an advantage over storing the unencrypted username and running the same query.

Why do you have a password cookie? You only need the password at login, to compare against the (hopefully hashed) value in your DB.

It was the only way I could originally think of to ensure that the client was actually logged in and not using a fake username cookie. They could fake the username easily enough, but if they know the user's password then they could just log in normally.

Right now I'm leaning towards a BASE64 encryption on the username (the same that I use for the password) so that it would be hard to fake, and then I could just decrypt it instead of running another query on every page.

graeme_p

5:41 pm on Apr 11, 2019 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



It was an issue back then. All you needed to do was to use an http library and a script to try different values for cookies. Its just a bit easier now.

For most sites the extra lookup for sessions or a username hash has a negligible impact. Unless you have a measurable impact its premature optimisation.

If your site is busy enough for it to matter then store sessions in redis or memcached, or store properly encrypted data in a cookie.

But either way I would still have to run a query to compare the stored hash to the database to get the actual username, right?


No you would put the hash in a cookie, and hash the value of the username cookie on each request and check the result matches the hash cookie.

Right now I'm leaning towards a BASE64 encryption on the username .... then I could just decrypt it instead of running another query on every page.


Base64 is not encryption. so not sure what you mean here.

NickMNS

6:05 pm on Apr 11, 2019 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Base64 is not encryption.

This is an important distinction that is worth repeating. Base64 is a type of encoding not encryption. A BASE64 string may appear to be the same as an encrypted string (AES/SHA/RSA, etc.) The difference being that a BASE64 encoded string can be converted back to plain text (ascii) by anyone. An encrypted value can only be converted back to plain text if one knows the encryption key.

I would still have to run a query to compare the stored hash to the database to get the actual username, right?

No. The text stored in the cookie is encrypted with a secret key before it is written to the cookie. The encrypted text cookie is stored on the user's device. Then when user returns to the server, the encrypted text from the cookie is read and decrypted, the decrypted text is then used for whatever is what meant for. As far as the server is concerned it always sees and uses the plain text and the user always sees the encrypted text. If the user messes with the text, you'll get garbage out when you decrypt it and you will have to handle that case. But the user will not be able to guess what another user's username should be in its encrypted state (they can guess, but not correctly).

I would also like reiterate Graeme's wise words above:
Its generally a bad idea to write your own authentication. Use a library or framework.

The framework should handle all that was described above.

csdude55

7:05 pm on Apr 11, 2019 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The difference being that a BASE64 encoded string can be converted back to plain text (ascii) by anyone. An encrypted value can only be converted back to plain text if one knows the encryption key.

True, but I think that the one I'm using is a little harder to decode. I use a custom alphabet so it's sort of like an encryption key, just easier for me to manage.

And it's not like I'm working with sensitive data here, so real encryption isn't that important for me. But for future readers, it's an excellent point to be made.

I appreciate all of the information, all! This has been very helpful :-)