HMAC / Javascript - where to store the secret? - javascript

The client gets it's secret for HMAC encryption after it's first login on the server - but what's the best way to store the secret on the (java-script) client? cookie, localStorage?
thx

Well the answer is, it depends. localStorage and cookies are not equivalent. Although they both can be used to store information on the client, they serve very specific goals. localStorage is meant to store application's data locally. It cannot be set directly from the server and is not sent to the server through HTTP headers either.
You may also have a look at sessionStorage.
However, cookies are typically created from the server (even if there's a JS API) through HTTP headers and they contain expiry information. Once set, they will be part of every client request's HTTP headers, allowing the server to access the information.
Both ways are probably equally secure since they both cannot be accessed from another domain. However if you are transmitting secure information you should probably do it through HTTPS as well.

The best way is pretty subjective.
If you must store it on the client (you must, I assume), then it can't be secure, it just can't.
Putting that aside, the best way depends on your situation.
Are you trying to target older browsers? Then you can't use local storage.
Since we've already removed security from the equation, your most far-reaching, cross-browser-compatible solution is to store it in a cookie.
That's also probably one of the easiest solutions, though certainly the least secure (since your only form of security here is obscurity, and cookies are... not obscure).

Related

Storing use information on a web server

I am storing some basic information to use in order to display information per user. I am currently using cookies to store and retrieve them, however I would like to employ a more secure tactic. I read that using local storage would be more secure and better to use, however, they don't seem to have any expiration date (like cookies) and unless you use a session storage, they will be stored indefinitely, which I don't want. However I don't mind using local storage if the information is encrypted, however with current encryption libraries, I have no idea how to use them.
Storing:
username
login attempts
whether the user is locked out or not
Some things to note: what I am storing is not being used for authentication, only to display error messages. I am using tomcat 8 to handle authentication and running the server (along with lockouts). Even though its not being used for authentication, I don't want to store the username unsecured or without expiration (1-2 days max).
Also, I'm not using an sql database (or other type) but plan to implement later, so don't suggest or ask about it.
I'm looking for the most secure method possible with relative ease, we have other security measures implemented, but don't want to leave any security holes open.
There is no such thing as secure that is purely client-side with two-way encryption. If you are able to decrypt something on the client-side, so can others.
Also, there are no particular security differences between session storage, local storage, and cookies. They're all client-side and able to be read by JavaScript on the same domain.
If you really want things to be secure, you have to store in on the server side, and transfer it only over HTTPS. Anything else is merely security through obfuscation, at best, which isn't real security.
As far as expiration, there is no automatic expiration with either local storage or session storage (other than the session storage will be cleared when the session ends). You could implement some with JavaScript, but that would only involve throwing away values when they are too old, and wouldn't happen until they visited your page.
The best you could do that is almost pure client-side would be to store some kind of key on the server, and when you go to decrypt, it needs to request the key (over HTTPS) from your server and use that to decrypt. That way, they can't decrypt it without having some kind of proper authentication onto your server.
However, if you're doing that, you might as well just store the info on the server in the first place.

Why can Cookies be set by PHP nut not Local Storage

Lets rewind to the days of cookies, ok not that far as they are old but still relevant. You can set them and read them with PHP; despite the fact they are a client side technology, you can also use JavaScript, fully client side.
Coming forward in to the future, HTML5 Local Storage, also a Client Side technology can not be set by PHP, you are solely reliant on JavaScript.
It seams as though this is the reverse way of doing it (taking away not adding). Surely to have the ability to set this data with PHP is helpful and possible somehow considering Cookies can be.
So why isn't it possible? What was the reasoning in not designing a way to do this?
Update Correct me if I am wrong, but localStorage is a replacement of Cookies, so does this not mean you are losing functionality?
Lets rewind to the days of cookies...You can set them and read them with PHP; despite the fact they are a client side technology...
No, they aren't. Cookies are primarily a client/server technology. They were specifically designed to allow the server to send information to the client that the client will then send back to the server. From the spec:
This document defines the HTTP Cookie and Set-Cookie header fields.
These header fields can be used by HTTP servers to store state
(called cookies) at HTTP user agents, letting the servers maintain a
stateful session over the mostly stateless HTTP protocol.
Although you can access them via client-side JavaScript, that isn't what they were created for, nor is it their sole purpose.
Web Storage (what you've called "HTML5 Local Storage") is client-side only. If you want to send that information to the server, you do it via ajax or by sending a form.
Why? That takes us into the land of speculation, but we already have cookies, whereas we didn't have a client-only way to store data prior to web storage. A client-only solution is very useful, not least because we can store a large amount of information without it being unnecessarily added to each and every HTTP request that client then makes to your server, which is a waste of bandwidth if the information is only needed client-side.
cookies … can set them and read them with PHP; despite the fact they are a client side technology
They aren't a client side technology. They are an HTTP technology. The are embedded in the communication protocol used between the client and the server.
Local Storage is a purely client side alternative to sessions and databases, which were already available on the server side.
It's purpose is for storing data that is too big for cookies. If you could edit it on the server, then the contents would have to be sent in every request, which would be very expensive. It would also turn Local Storage into "Cookies without the restriction on size".

Why isn't localStorage used instead of cookies? ( and in other cases as well )

According to MDN it is suppose to be more secure than cookies for storing persistent data on the client.
However, checking the localStorage of facebook.com, twitter.com, and linkedin.com I can see that it is not being used.
Oddly, linkedin does have the key ( in localStorage ) 8df when logged in , but trying to access it throws an error.
My guess (hopes this qualifies has an answer)
Web Storage is compatible with most common browsers: http://caniuse.com/namevalue-storage .
For things that don't need to transit with session: what probably happens is that cookies is most commonly known and easy to use. There are lots of companies with average skilled ppl, who will run away when confronted with things out of their confort zone.
Edit after Python Fanboy's answer (+1 from me): read his answer.
localStorage has this drawback which cookies doesn't have: it's stored values aren't sent automatically with all HTTP requests so without more implementation Your server won't know what's stored in browser's localStorage.
localStorage is supported in IE since IE8.
According to MDN it is suppose to be more secure than cookies for storing persistent data on the client.
Taking a quick look at Facebook's cookie, for example, I see things like userid, authentication tokens, presence indicator for chat, and window size. (Not posting my cookie here for obvious reasons).
The feature that makes cookies "less secure" (cookies are sent with the HTTP request) is the feature they need in this case because it's part of their communication protocol. Authentication tokens are useless if they aren't sent to the server for, well, authentication.
Simply put, they aren't using localStorage in this case because they aren't trying to store things locally.

Is there any downside to storing an API key in a browser cookie?

We've got an app with a json API. We use Javascript in the browser to send ajax calls to it. Each API call requires an API key.
I was planning to implement a login API that would accept a username and password and return the API key for that particular user. The key would go in a cookie and get passed back with every API request. (You would still be able to include it in the json request; the cookie would be a fallback.)
The big benefit of this scheme is that we wouldn't need to maintain sessions on the server side. Everything on the server side would be stateless. There's a significant benefit to stateless operation when you're in a clustered environment.
Is this a bad idea? Is it secure? Is there a better way?
Assume that we're running over https.
Nope, the way you mention, your API keys are not secure this way even though you are using https. That's because the API key now lives on your browser and is susceptible to being exposed either by browser plugins, scripts, etc.
Another thing to consider here is how long are your tokens valid. In such cases it is recommended to have a short API token expiration time.
Fortunately, a lot of people have the same requirement and OAuth 2 spec has a Implicit Grant case flow just for the use case you mentioned. You can look at that and decide your approach,
https://www.rfc-editor.org/rfc/rfc6749#section-4.2
If you don't need support for older browsers, and you only need access to the api key client side, then you can use Local Storage instead, that way you wont have to send a cookie to and from the server, and theres no cookie that can be stolen.

with sessionStore and webSockets, are cookies still needed?

if the following conditions are met:
all pages are static (eg, templates to be filled in via websocket data)
all pages are public
session id and status communicated through websocket
client session state stored via sessionStorage and/or localStorage
is there still a need for cookies?
The localStorage/sessionStore can indeed replace cookie Storage. Both are on the client.
The neat thing about cookies is that they are auto appended to any HTTP request. There is absolutely nothing to do from a coding standpoint. But since you want to use websockets, it doesn't apply - you will still need to do wiring with the sessionid stored in the localStorage.
So the answer to your question is "No" you don't need cookies in your scenario
If the pages are 100% static then there is no state, so the question becomes moot, since no mechanism at all is required for preserving state across requests.
However, if any part of the pages are dynamic then cookies may still be necessary for preserving state across multiple sessions. Since cookies are stored client side but passed to the server with every request they are a mechanism for synchronizing client and server state. Of course, you could implement this via an AJAX request and localStorage yourself if you wanted to.

Categories

Resources