0

I'm developing a mobile app where I wish to implement a simple user authentication, and as i'm new to hybrid mobile developing with its front-end restrictions, i'm quite terrified by the idea of holding any back-end related data in the form of localStorage / sessionStorage / ngCookies (as I have seen some people do).

So my question is, how secured can these methods be of holding such data? Do app users have the ability to access and modify let's say... the sessionStorage, from the application itself? Cause it sure is easy on the web.

Sorry if it's a stupid question, I just don't wish to take any security risks when it comes to this. Much thanks for any help!

Shay
  • 2,060
  • 2
  • 16
  • 22
  • If you use cookies for storing user related data that is needed for your server, those kind of cookies can be encrypted on server side before sent to the client. You can still access such cookies with ngCookies but the only harm that can be done is that some injected code can invalidate them. If somehow your encryption scheme is revealed and they become readable to an attacker, you can invalidate modifications to them by appending a signature (created with a secure hash algorithm) on every store and check your the signature on every retrieval. – diegoperini Apr 01 '15 at 10:08
  • Thanks for the response! But what about a simple boolean that validates whether the user is logged in or not? Would you use a separated token for true or false? – Shay Apr 01 '15 at 10:28
  • Once you use cookies for authentication, you end up dealing with problems like 'Who is logged in?', 'How long is he/she staying logged in?', 'Is the computer using a public internet?' etc. In the end, an easy way to represent a state that belongs to a specific user (hence the cookie) is to stringify some object that can be reverse stringified (parsed) again which in the end will represent the same state. If the stored string is invulnerable to modifications and/or unreadable to the naked eye of a computer, it is safe to store as a cookie. – diegoperini Apr 01 '15 at 11:26
  • Unreadable to a computer's naked eye means it is not feasible to decrypt or deduce encryption/signing scheme in a time that the stored state stays valid. – diegoperini Apr 01 '15 at 11:30
  • Side note: Since it is possible to store any kind of data in a state object, some servers send cookies that store user IP, geolocation and such to invalidate accesses from sources that somehow acquired the same cookie and kept it without modifying. – diegoperini Apr 01 '15 at 11:33
  • Thanks a lot for your detailed answer, I had to read it a few times but I think I got it! I worked it out with encrypted data in storage eventually :) – Shay Apr 02 '15 at 08:33

1 Answers1

2

TLDR; Cookies and storages should be assumed to be stored in plain text and accessible by client side script that comes from the same domain. Assume the worst; anything can go wrong with your script due to bugs or XSS attacks. If the data will be used both by the client and the server back again, most definetly sign it. If the data is only relevant to server side code, sign and encrypt it. If the data is only for printing stuff to screen or DOM evaluation, leave it plain text.


Let's be clear about what cookies, session storages and local storages are before beginning to an example implementation.

Cookies are data created by server or client, stored in plain text by browsers, that is sent on every http request to the server if the path matches. They are good for storing authentication tokens, meta data regarding tracking, analytic, website interface preferences, shopping carts and many other.

Storages are - as indicated by their name - storage space assigned to your domain and only scripts from your domain and XSS attacks can alter it. This means, if you use them for the purposes I listed above, you have to append data stored in them to your HTTP requests by hand. If your site depends on many async HTTP calls, it is not wrong to use storages like cookies. Otherwise they are useful for caching things like template data and site resources.


If you use cookies for storing user related data that is needed for your server, those kind of cookies can be encrypted on server side before sent to the client. You can still access such cookies with ngCookies but the only harm that can be done is that some injected code may invalidate them. If somehow your encryption scheme is revealed and they become readable to an attacker, you can invalidate modifications to them by appending a signature (created with a secure hash algorithm) on every store and check your signature on every retrieval. Let's illustrate that process.

$userState = json_encode($yourStateObjectOrAnAssociativeArray);
$sign = my_hash($userState);
$encryptedState = encrypt($userState);
setcookie("user" , $encryptedState);
setcookie("sign" , $sign);

Here we have encoded our state as JSON, then first generated a hash. You can use some SHA1, SHA256 and such with a stored key you choose to come up with a my_hash() function. Below is an example that is correct but you shouldn't use it since even I shouldn't know your algorithm.

// hash() is reserved so use something else
function my_hash($object) {
    return sha1(md5($object) . "some giberish key that is stored as config data or in a db" . sha1($object))
}

Note that my_hash() is not extremely secure since it uses a static string as key and a generation structure that is not complex. In the end, it is sha1() of some randomly structured string. It is sufficient for a cookie sign though.

You can write your own encrypt() / decrypt() pair by using AES encryption or some equally secure algorithm of your choice. Here is an example from this site.

Now our cookie is stored and ready to be sent on the next request. Below is how you decrypt and validate your cookie from the example above.

$sign = $_COOKIE["sign"];
$encryptedState = $_COOKIE["user"];

$userState = decrypt($encryptedState); //If this fails, it indicates someone tried to replace your cookie by hand, it is a failed attack

$assoc = true; //If true, json_decode returns array, otherwise it returns an object
$yourStateObjectOrAnAssociativeArray = json_decode($userState, $assoc); //If this fails, it indicates someone tried to replace your cookie by hand, it is a failed attack

if($sign == my_hash($yourStateObjectOrAnAssociativeArray)) {
    //Noone modified your cookie, you are safe
    //Do something with it
}
else {
    // Someone tried to replace your sign cookie to imitate your server but he failed
    // or
    // Someone managed to decrypt your cookie and modified it but failed to generate a valid sign (very unlikely)
    // You are still safe
    // Log this line and check every once in a while to detect unsuccessful hackers
}

The good part of using a state object is that it can be used to implement many kinds of restrictions and tracking mechanisms. For example storing system time during creation of your cookie gives you the chance to expire it later. Embedding client IP is a way to restrict sharing cookies across networks.

Community
  • 1
  • 1
diegoperini
  • 1,796
  • 21
  • 37
  • Wow, thank you for a VERY detailed response! Props for that. :) You definitely expanded my views on back-end security! Do you have a blog or somewhere you write in? I'll be definitely interested to follow more similar concepts. :) – Shay Apr 03 '15 at 12:19
  • I'm glad I could be a help. You can go to my blog, the link is in my profile. I plan to write such posts in the future. Back-end security may be good start as you suggested. Thanks :) – diegoperini Apr 04 '15 at 15:49
  • I like it. :) I'm playing with the cmd a lot these days, so it feels very natural and fun for me. Looking forward for some more posts, i'll be watching! :) – Shay Apr 04 '15 at 21:58
  • 1
    Here is my latest post regarding the same subject here: http://blog.dperini.com/backend%20security/2015/04/23/client-is-a-valid-storage/ – diegoperini Apr 23 '15 at 03:49
  • Very informative post diegoperini :) Thanks for further opening my views on encryption and work methods. At first I thought it would be nuts to trust client's storage, but now I see that although the door is open, it doesn't mean that its easy to pass it. :) Thanks for sharing! – Shay Apr 23 '15 at 18:41