How to securely store localstorage in angular 5 - javascript

Is there any way to store localstorage securely, like encrypting and decrypting the localstorage data. I don't want other users to manipulate the localstorage data.
If that is not possible with localstorage, what are the other ways to store data at client side?
I have seen websql, but that is also get manipulated easily by writing queries in console.
Note: Can you please provide the solution for Angular 2+ !

Contrary to the other answer, you can securely store any value in the client, where by "securely" I mean the value is not known to the client and/or cannot be modified. The storage mechanism can be localStorage, websql or whatever else. The catch is that Javascript code will not be able to read and/or modify such a value either, because obviously Javascript is the client from what you want to protect such data.
If you have a server-side secret (a key), you can use that to encrypt (for confidentiality) and/or sign (for integrity) any data sent to the client. This is how frameworks like Rails handle sessions by default without server-side persistance and still relatively securely.
Note that simply encrypting a cookie on the server will not necessarily authenticate its contents (see authenticated encryption), and also such a cookie would be vulnerable to replay attacks, against which you can use a timestamp or a nonce. You have to care about forward secrecy if you need it. So in short you have to take care of stuff yourself, which is not straightforward, but not impossible either.
If you only sign data but not encrypt it, Javascript may have access to it, but still won't be able to modify.

No there isn't any way to store data in client side which client won't be able to manipulate.
In angular, you can save data in services but that will be cleared if user refreshes the browser.

Related

Is it possible to sign/encrypt data on the client-side to ensure it was not manipulated by the user?

I save information in local storage and I want to make sure the user didn't replace the data or had fun with it.
The client receive an object, javascript analyse it, do it's thing and store some of it in the browser's local storage.
The data is sent to the server every 30 seconds and the server replies by another object, based on the previous data sent.
The process happens often so it would be preferable to avoid sending the server tons of data and make heavy query to verify the integrity.
I know Javascript in the client is prone to debugging, reverse engineering etc. But it would definitely add a layer of security so at least some people wouldn't bother. (Security through obscurity)
My initial thought was to make a checksum of the value I want to store, send it to the server and compare it to the checksum stored. If the result mismatch, dismiss the data on the client-side. I think it would be preferable to avoid storing in database and be able to check if it's legit with some function.
I would prefer if the data stored would look like a token (like a signed or encrypted base64 string) rather than raw data as it would leak some information about how the code works and may make it vulnerable.
Is there libraries or method of doing so that could help me in my journey?
Is it possible to sign/encrypt data on the client-side to ensure it was not manipulated by the user?
Short aswer - No, it is not possible.
Long answer - Any message authentication code (signature, hmac, ..) requires a secret value. As soons as you do the signing on the client side throuhg JavaScript, there is no way you can prevent the user to access the secret or modify data.
Take in account the user even may modify the application to change the client-side validation. Long story short - never trust user's input, you have to always validate data on the server side.
Suggestion - you may send the data to a server service and the server could sign/hmac the data. The same way you could validate the data integrity.
But it would definitely add a layer of security so at least some people wouldn't bother. (Security through obscurity)
In my opinion - it doesn't matter much. If the user doesn't care, he won't modify the data. If you have a dedicted user, no level of obfuscation will stop him.
I would prefer if the data stored would look like a token (like a signed or encrypted base64 string)
Nothing prevents you to do so.

Verifying data that is encrypted in the browser

We have a file upload system that PGP encrypts data in the browser before it is sent to our servers. The files are then viewed by us in a specially designed local program. We decided this was the safest way to store that data. One downside to this we find in our own testing is that we can really upload anything at all, random strings etc., because we can't verify what that data is once encrypted without keeping our private keys on a server that is connected to the internet. It seems to me that this is a pretty big potential flaw, though I can't put my finger on exactly what could be done with it. Aside from sanitizing and checking data before viewing it, what can we do to mitigate the issue? Should we take another route entirely for protecting the data?
Edit: We realized the public key used to encrypt could simply be changed by an attacker and they'd have access to all files encrypted from that point. The current suggestion is to encrypt using hashed user password+salt generated at login time and then storing that key on another server (protected by master password) so that we too can view them. The issue of changing keys seems to be mitigated by this (though keys could plausibly be intercepted while being sent to the secure storage server).

Prevent Access to Local Storage via Developer Tools?

I know there has been a lot of discussion on the evils vs. the good of local storage. There have also been Chrome hacks for disabling a user's/visitor's ability to run JavaScript from the console which have had limited success.
None of these have addressed my question: can you prevent a user from editing local storage values in their browser?
This will never be the ideal or permanent solution to a current issue, I just need a way to do this until we can refactor the codebase to use IndexedDB.
EDIT: There is no sensitive data being handled in local storage for this app which is only available to local users on an in-house network. There are some data points that a handful of users have learned can be edited and it is these users the project owner is concerned about.
No, you can't. Even if there is a temporary 'solution' or hack that seems to work, it is still the web, so there is no way to prevent access to it. Trying to prevent a user from accessing a resource on their own system is doomed to fail.
Methods I can think of inside and outside the browser to read from and write to the local storage:
Inject JavaScript in the page to read the local storage;
Create your own browser or browser plug-in;
Read the SQLite databases in %LocalAppData%\Google\Chrome\User Data\Default\Local Storage.
You cannot do this. There is no way to control a user's browser in this way, and there should never be. That is antithetical to the nature of the Internet. Your server publishes code. People consume that code using some kind of browser. That's it. You have no control over what reads your code or what it does with the code once you've served it up.
Your approach to security is completely wrong. You cannot secure this on the client's side.
It's up to you to use localStorage securely from the get-go. That means you cannot trust any data stored there, and you cannot store anything there that you don't want the user to read. There, or in cookies, or in IndexedDB, or in any client-side data store. Security comes from inherently mistrusting any user-submitted data. You need to validate any and all data that a user sends to your server, full stop. Trying to prevent them from changing the data cannot work, because they can just write their own data. They can produce a request that will send literally anything to your server.
If you're storing sensitive data in localStorage or any other client-side data storage, you're doing it completely wrong, and you need to abandon that approach, because it cannot be salvaged.

How can i get the HTML5 Local storage values in server side

I am a .Net developer, I know that the HTM5 localstorage is client-side storage technique. I want to get the local storage data on the server-side.
For getting cookie value from server-side we have Request.Cookie in ASP.NET. Is there any solution like that to take the local storage value directly on the server-side? Please guide me. I am using the .net 4.0 framework
Thanks,
Jibu
You will need to pass this information from the client to the server using standard HTTP techniques. Using javascript you could fill:
Hidden fields
Query string parameters
POST
Ajax call to the server
...
It will all depend on how your application is organized, what kind of information is being stored, its volume, whether you want to redirect or not, ... But in all cases this should be done using javascript since that's the only way to access data stored in localStorage.
No. The whole point of local storage is that it is local. One of the advantages of it over cookies is that you can store lots of data in it. One of the advantages of cookies is that they are tiny so the overhead of including them in every HTTP request to a given host is small. There two advantages are incompatible so you won't want them in a single technology.
If you want to get the data on the server, then you need to get the client to send it explicitly (e.g. via Ajax).
This is a widescope question. (like the length of a piece of string), but Ill try to make this helpful:
If you have values in local store in webserver I assume your webserver is JSON? Or did you use the sql local storage option?
Regardless of type of storage, you need to build an interface that both handles:
a) Reading data from your local database -> its important to involve some kind of date or index value in here if you are aiming to sync databases... this is to make sure you send IN ORDER all transactions / updates which are in your database. For this to happen you must store your data not only as tables with inforamtion but also tables that contain events of when updates happened and what was updated. (change tables). This will help check in the server end that everything is sync and also means you dont send data to the server that is not needed and can be kept locally. ((otherwise what is the point of local store if you cant save yourself server database space by only syncing waht is necessary?)
b) A HTTP local server to send the data to your destination client server or database server, etc (however you have set your infrastructure) - I recommend using industry standards for your language and server, which is Ajax and JQuery. If you do a lot of streaming of data then i recommend looking into RXjs with Ajax to get a http interface built (interface in this sense just means a way to expose your client like an API and post http calls)
c) An event loop to handle how often and what triggers the synchronization so that you dont destroy your users machine with overdoing it (you dont want to do this too often, but also want to it to be meaninful rather than "every night" maybe user enabled whenever you detect an event which triggers wifi available again.) - i recommend using native wifi reading capabilities built into Apache Cordova and also industry standards for your server setup (for example Express.js for Node.JS).
Obviously the backend server needs to have its API set up and authentication / authorizations, etc.

How can I send data to a user that will persist between web page views, but which won't be resent to the server?

I want to send some data to a user after they log in to a web site, some kind of secret string for encryption.
I want to allow them to navigate around the web site, and I want to be able to use javascript on their machine to encrypt data before it's sent back to the server. Note: This will be in addition to using SSL.
I don't want to use cookies for this because they are sent to the server on each request.
So my aim is to have some data that will be sent across the wire only once for the whole session, but that when the user visits multiple pages, javascript will be able to access this secret. To be clear I never want to see the user's decrypted data, nor be able to.
Is this possible, maybe using HTML5 persistence or something? I need a cross-browser compatible solution please that will ideally work with IE6 (so that might shoot down any HTML5 magic).
Thanks
If you are worried about snooping, use HTTPS. It sounds like a pretty fragile encryption mechanism though, why not go more 'traditional'?
I'd doubt you can do this. A session is normally tied to a cookie (ie jsessionid), so to tie it to the "session" (ie you said "some data that will be sent across the wire only once for the whole session"), and have it available to the user, you need to put it in a cookie.
You can use localStorage on HTML5-supporting browsers (IE8, FF3+, Chrome, Safari 4+, Opera 9+). You can fall back to userData for IE6 and IE7. That gives you a guaranteed minimum of 64 KB of data on all platforms (minimum userData size).
There's a library that encapsulates the various strategies for storing data locally: PersistJS
I use this to store client-side state that doesn't need to be sent to the server with every request (e.g. resizable panel dimensions). I don't think it could offer any additional security though, because any attacker that can decrypt the SSL stream can get at your data, because they can observe all your javascript code.
You could use a RIA plug-in like Flash or Silverlight. Both have mechanisms for storing data locally w/o sending it back to the server on each request. Java might as well.
How about keeping the user on the secure page and sending the encrypted data back with ajax calls?
I also remember seeing a php script that would load a given page into an iframe based on some criteria. I think the example I saw was just a demo, where you selected a page from a select form. The page containing the iframe can be used to persist data.
I think i'll take inspiration from the banking world and perform all of the encryption on the server. I can think of a way that I could generate a private key from the user's password making it impossible for me to decrypt data without the user being logged in.
I don't think there's a robust solution to my initial question, but thanks for the responses.

Categories