Are there any drawbacks to using localStorage instead of Cookies? - javascript

On my previous websites, I used to use a cookie to display a pre-home page only on the first visit. That worked great (see for example here), but using cookies is not so trendy today, so I want to avoid it as much as possible.
Now, my new website projects almost always have pre-home launched via javascript (showing a modalbox), so I don't need to do any action on the server side. I'm considering to use HTML5 localStorage instead of cookies, with a fallback on cookies if the browser does not have localStorage. Is this a good idea? What is the impact in terms of usability, privacy protection and website performance?
Using localStorage will improve usability for users that have disabled cookies. But I know that some HTML5 features are only opt-in (like geolocalisation) in some browser. Is there any restriction like that for localStorage on any browser ? Is there any case where I will get a JS error if localStorage is available but deactivated for my site ?

Usability
The user will not know if you are using localStorage or a cookie. If a user disable cookies, localStorage will not work either.
Performance
There is no noticeable speed difference between the two methods.
sessionStorage
sessionStorage is only for that browser tab's session. If you close the tab, the session will be lost and the data will be lost too, it's similar to a session variable on any backend language.
localStorage
localStorage will be available for any tab or window in the browser, and will exist until it is deleted by the user or the program. Unlike a cookie, you cannot setup expiration. localStorage has a much larger storage limit as well.
Your Questions
You are not using this data server side, so you don't need a cookie. localStorage is never sent to the server unlike a cookie.
If the user disables the cookies, localStorage will not work either.
Fallback Example
You can use a Modernizr to verify if localStorage is available and if not, use store a cookie instead.
if (Modernizr.localstorage) {
// supports HTML5 Storage :D
} else {
// does not support HTML5 Storage :(
}
You can also forego Modernizr and use the check typeof Storage !== 'undefined'.

Comparing LS vs cookies is comparing apples to oranges.
Cookies and LS are completely different things for different purposes. LS is a tool that allows your client (javascript code) to store its data locally, without transmitting it to the server. Cookies is a tool for the client-server communication. The whole point of cookies is to be sent over with each request.
In the past cookies were often abused to emulate the local storage, just because it was the only possibility for a javascript application to write anything to the client's hard drive. But generally LS is not a replacement for cookies, so if you need something that both client and server should read and write, use cookies, not LS.

One point to add, unlike cookie normally shared cross protocol, the storages stick to same-origin policy. As a consequence sites share the same domain but hosted on different protocol do not share the stored data.
Say if your website need to work across http and https. For example, when user clicked the "purchase link" they will land on https secured checkout, then the checkout won't be able to retrieve the data previously stored on http site, even when they share the same domain.

It doesn't look easy for the server to read the localStorage. That may come in handy though, knowing your data is all client-side, making it safe from sniffing.
Cookies can't be written over, only added to and read:
alert(document.cookie);
document.cookie = "nope";
alert(document.cookie);

The one thing I didn't like about using 'localstorage' is that all your script code is visible when you 'inspect' (F12) the page. Go into SOURCES and from the left panel locate your website name and open it. All your code within the tags is totally visible. So if you've got some sensitive values on display, liked hashed passwords, special words, they all there for the world to see. I'm not sure what the world will do with this info, but it's not very secure.

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.

Can localStorage do everything that cookies can do? [duplicate]

I want to reduce load times on my websites by moving all cookies into local storage since they seem to have the same functionality. Are there any pros/cons (especially performance-wise) in using local storage to replace cookie functionality except for the obvious compatibility issues?
Cookies and local storage serve different purposes. Cookies are primarily for reading server-side, local storage can only be read by the client-side. So the question is, in your app, who needs this data — the client or the server?
If it's your client (your JavaScript), then by all means switch. You're wasting bandwidth by sending all the data in each HTTP header.
If it's your server, local storage isn't so useful because you'd have to forward the data along somehow (with Ajax or hidden form fields or something). This might be okay if the server only needs a small subset of the total data for each request.
You'll want to leave your session cookie as a cookie either way though.
As per the technical difference, and also my understanding:
Apart from being an old way of saving data, Cookies give you a limit of 4096 bytes (4095, actually) — it's per cookie. Local Storage is as big as 10MB per domain — this Stack Overflow question also mentions it.
localStorage is an implementation of the Storage Interface. It stores data with no expiration date, and gets cleared only through JavaScript, or clearing the Browser Cache / Locally Stored Data — unlike cookie expiry.
In the context of JWTs, Stormpath have written a fairly helpful article outlining possible ways to store them, and the (dis-)advantages pertaining to each method.
It also has a short overview of XSS and CSRF attacks, and how you can combat them.
I've attached some short snippets of the article below, in case their article is taken offline/their site goes down.
Local Storage
Problems:
Web Storage (localStorage/sessionStorage) is accessible through JavaScript on the same domain. This means that any JavaScript running on your site will have access to web storage, and because of this can be vulnerable to cross-site scripting (XSS) attacks. XSS in a nutshell is a type of vulnerability where an attacker can inject JavaScript that will run on your page. Basic XSS attacks attempt to inject JavaScript through form inputs, where the attacker puts alert('You are Hacked'); into a form to see if it is run by the browser and can be viewed by other users.
Prevention:
To prevent XSS, the common response is to escape and encode all untrusted data. But this is far from the full story. In 2015, modern web apps use JavaScript hosted on CDNs or outside infrastructure. Modern web apps include 3rd party JavaScript libraries for A/B testing, funnel/market analysis, and ads. We use package managers like Bower to import other peoples’ code into our apps.
What if only one of the scripts you use is compromised? Malicious
JavaScript can be embedded on the page, and Web Storage is
compromised. These types of XSS attacks can get everyone’s Web Storage
that visits your site, without their knowledge. This is probably why a
bunch of organizations advise not to store anything of value or trust
any information in web storage. This includes session identifiers and
tokens.
As a storage mechanism, Web Storage does not enforce any secure
standards during transfer. Whoever reads Web Storage and uses it must
do their due diligence to ensure they always send the JWT over HTTPS
and never HTTP.
Cookies
Problems:
Cookies, when used with the HttpOnly cookie flag, are not accessible through JavaScript, and are immune to XSS. You can also set the Secure cookie flag to guarantee the cookie is only sent over HTTPS. This is one of the main reasons that cookies have been leveraged in the past to store tokens or session data. Modern developers are hesitant to use cookies because they traditionally required state to be stored on the server, thus breaking RESTful best practices. Cookies as a storage mechanism do not require state to be stored on the server if you are storing a JWT in the cookie. This is because the JWT encapsulates everything the server needs to serve the request.
However, cookies are vulnerable to a different type of attack:
cross-site request forgery (CSRF). A CSRF attack is a type of attack
that occurs when a malicious web site, email, or blog causes a user’s
web browser to perform an unwanted action on a trusted site on which
the user is currently authenticated. This is an exploit of how the
browser handles cookies. A cookie can only be sent to the domains in
which it is allowed. By default, this is the domain that originally
set the cookie. The cookie will be sent for a request regardless of
whether you are on galaxies.com or hahagonnahackyou.com.
Prevention:
Modern browsers support the SameSite flag, in addition to HttpOnly and Secure. The purpose of this flag is to prevent the cookie from being transmitted in cross-site requests, preventing many kinds of CSRF attack.
For browsers that do not support SameSite, CSRF can be prevented by using synchronized token patterns. This
sounds complicated, but all modern web frameworks have support for
this.
For example, AngularJS has a solution to validate that the cookie is
accessible by only your domain. Straight from AngularJS docs:
When performing XHR requests, the $http service reads a token from a
cookie (by default, XSRF-TOKEN) and sets it as an HTTP header
(X-XSRF-TOKEN). Since only JavaScript that runs on your domain can
read the cookie, your server can be assured that the XHR came from
JavaScript running on your domain. You can make this CSRF protection
stateless by including a xsrfToken JWT claim:
{
"iss": "http://galaxies.com",
"exp": 1300819380,
"scopes": ["explorer", "solar-harvester", "seller"],
"sub": "tom#andromeda.com",
"xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e"
}
Leveraging your web app framework’s CSRF protection makes cookies rock
solid for storing a JWT. CSRF can also be partially prevented by
checking the HTTP Referer and Origin header from your API. CSRF
attacks will have Referer and Origin headers that are unrelated to
your application.
The full article can be found here:
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
They also have a helpful article on how to best design and implement JWTs, with regards to the structure of the token itself:
https://stormpath.com/blog/jwt-the-right-way/
With localStorage, web applications can store data locally within the user's browser. Before HTML5, application data had to be stored in cookies, included in every server request. Large amounts of data can be stored locally, without affecting website performance. Although localStorage is more modern, there are some pros and cons to both techniques.
Cookies
Pros
Legacy support (it's been around forever)
Persistent data
Expiration dates
Cookies can be marked as HTTPOnly which might limit XSS atacks to user browser during his sesion (does not guarantee full immunity to XSS atacks).
Cons
Each domain stores all its cookies in a single string, which can make
parsing data difficult
Data is unencrypted, which becomes an issue because... ... though
small in size, cookies are sent with every HTTP request Limited size
(4KB)
Local storage
Pros
Support by most modern browsers
Persistent data that is stored directly in the browser
Same-origin rules apply to local storage data
Is not sent with every HTTP request
~5MB storage per domain (that's 5120KB)
Cons
Not supported by anything before: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
If the server needs stored client information you purposely have
to send it.
localStorage usage is almost identical with the session one. They have pretty much exact methods, so switching from session to localStorage is really child's play. However, if stored data is really crucial for your application, you will probably use cookies as a backup in case localStorage is not available. If you want to check browser support for localStorage, all you have to do is run this simple script:
/*
* function body that test if storage is available
* returns true if localStorage is available and false if it's not
*/
function lsTest(){
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
/*
* execute Test and run our custom script
*/
if(lsTest()) {
// window.sessionStorage.setItem(name, 1); // session and storage methods are very similar
window.localStorage.setItem(name, 1);
console.log('localStorage where used'); // log
} else {
document.cookie="name=1; expires=Mon, 28 Mar 2016 12:00:00 UTC";
console.log('Cookie where used'); // log
}
"localStorage values on Secure (SSL) pages are isolated"
as someone noticed keep in mind that localStorage will not be
available if you switch from 'http' to 'https' secured protocol, where
the cookie will still be accesible. This is kind of important to
be aware of if you work with secure protocols.
Cookies:
Introduced prior to HTML5.
Has expiration date.
Cleared by JS or by Clear Browsing Data of browser or after expiration date.
Will sent to the server per each request.
The capacity is 4KB.
Only strings are able to store in cookies.
There are two types of cookies: persistent and session.
Local Storage:
Introduced with HTML5.
Does not have expiration date.
Cleared by JS or by Clear Browsing Data of the browser.
You can select when the data must be sent to the server.
The capacity is 5MB.
Data is stored indefinitely, and must be a string.
Only have one type.
Key Differences:
Capacity:
Local Storage: 10MB
Cookies: 4kb
Browser Support:
Local Storage: HTML5
Cookies: HTML4, HTML5
Storage Location:
Local Storage: Browser Only
Cookies: Browser & Server
Send With Request:
Local Storage: Yes
Cookies: No
Accessed From:
Local Storage: Any Window
Cookies: Any Window.
Expiry Date:
Local Storage: Never Expire, until done by javascript.
Cookies: Yes, Have expiry date.
Note: Use that, what suits you.
It is also worth mentioning that localStorage cannot be used when users browse in "private" mode in some versions of mobile Safari.
Quoted from WayBack Archive of MDN topic on Window.localStorage back in 2018:
Note: Starting with iOS 5.1, Safari Mobile stores localStorage data in the cache folder, which is subject to occasional clean up, at the behest of the OS, typically if space is short. Safari Mobile's Private Browsing mode also prevents writing to localStorage entirely.
Cookie:
is accessible by JavaScript so Cookie's data can be stolen by XSS
attack(Cross Site Scripting attack) but setting HttpOnly flag
to Cookie prevents the access by JavaScript so Cookie's data is
protected from XSS attack.
is vulnerable to CSRF(Cross Site Request Forgery) but setting
SameSite flag with Lax to Cookie mitigates CSRF and setting SameSite flag with Strict to Cookie prevents
CSRF.
must have expiry date so when expiry date passes, Cookie is
deleted automatically so even if you forgot to delete Cookie,
Cookie is deleted automatically because of expiry date.
is about 4KB as a common size (depending on browsers).
Local Storage:
is accessible by JavaScript so Local Storage's data can be stolen by XSS
attack(Cross Site Scripting attack) then, as logn as I researched,
there are no easy preventions for Local Storage from XSS
attack.
is not vulnerable to CSRF(Cross Site Request Forgery).
doesn't have expiry date so if you forgot to delete Local Storage
data, Local Storage data can stay forever.
is about 5MB as a common size (depending on browsers).
I recommend using Cookie for sensitive data and Local Storage for non-sensitive data.
Well, local storage speed greatly depends on the browser the client is using, as well as the operating system. Chrome or Safari on a mac could be much faster than Firefox on a PC, especially with newer APIs. As always though, testing is your friend (I could not find any benchmarks).
I really don't see a huge difference in cookie vs local storage. Also, you should be more worried about compatibility issues: not all browsers have even begun to support the new HTML5 APIs, so cookies would be your best bet for speed and compatibility.
Local storage can store up to 5mb offline data, whereas session can also store up to 5 mb data. But cookies can store only 4kb data in text format.
LOCAl and Session storage data in JSON format, thus easy to parse. But cookies data is in string format.

can localStorage totally replace 3rd party cookies? [duplicate]

Is the newly introduced localStorage facility in html5 a replacement for cookies? Does localStorage help in making the http from stateless to stateful. Or is the localStorage an addition to the cookies. Do you still need to use cookies to track the user or even that can be done ny localStorage?
Local Storage allows client-side javascript to save state on a local machine (if LocalStorage is supported). That is one thing that client-side javascript might use cookies for, but cookies are also used for other things that LocalStorage cannot replace.
For example, LocalStorage is never seen by a server so if a server wants to keep track of some client state itself or track something across multiple pages on a domain, then the server can't use LocalStorage for that and will likely still use cookies. Cookies for a domain are sent to the server with each request on that domain (thus enabling things like authenticated login across all pages in a site). This is something that LocalStorage cannot do.
LocalStorage has nothing to do with HTTP; it's a purely client-side feature.

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 it possible for a user to modify site javascript in browser?

I don't know a lot about security, but I'm trying to figure out how to keep my site as safe as possible. I understand that as much stuff that I can handle on the backend the better, but for instances where I'd like to hold some variables on the client, is that stuff utterly unchangeable?
For instance, if I set a global variable to the user's role (this is a pure AJAX web app so a global variable is always available), is it possible by any software to edit javascript within the browser so that a user might change their role?
Security is a big topic in the web development world and it is important for you to determine how secure your web application should be.
There are 3 parts for you to notice
Frontend (the website)
everything here is insecure, whatever shown on you in the browser could be changed or modified. Just go to the debug console and you could change the variable and rerender the html page again
Transportation level (https)
web communication is based on the http(s) protocol that allows you to communicate between your server and client. Using https will prevent you from man in the middle attack
Backend
always make sure to authenticate and check the data sent from your client (POST, PUT, DELETE)
Prevention
The good thing is even you change the variable of the client side, it only appears on that client session and doesn't effect any others. There are few ways you could increase your security in your frontend
Obfuscate
this means make your source code harder to read. You could try to use tool like minification, and concatatenata your source code.
Data
Never ever store user sensitive data (password, user info) in the client side, since people could just change and see it
This should get you learning more about security
With developer tools if you run in debug mode with breakpoints then you can change values of variables.
All data that goes to the client can be viewed and tampered. There are alot of ways to do that (Developer Tools, HTTP Proxy, ...).

Categories

Resources