if you write data to local storage with javascript on Android like this:
localStorage.data = "test";
Can this data be access and viewed in some way? I have some important data to save like user personal information and I would not like for anybody to see this data (even if they put some effort in this). Solutions?
There aren't protected at all if you have access to the browser.
Anybody connecting to your site from the user's browser can simply type console.log(localStorage) in the developer's tools (use Ctrl-uppercase-i on most browsers) to see it in clear.
A solution might be to encrypt the data using a server provided key, but this wouldn't be so secure : it's easy (for example using an extension) to change the executed javascript once you get access to the browser (and you have the user to come back to the site). I'd suggest to store on the server those data.
I assume you are talking about a technical exploit rather than someone physically getting hold of the actual device?
If so, it is my understanding that only code on the domain from which the data was saved can access it. So you'd potentially be vulnerable is someone managed a XSS attack or you incorrectly included someone else's script.
Related
In this use case, the server send an encypted blob to the browser and the the javascript on the browser subsequently requests the decryption key from the server and decrypts the blob to usable content.
Is there a way to protect this key on the browser from an attack by a bookmarklet or browser plugin or the user stepping through the javascript debugger on browser? Or atleast make it a slightly harder problem for the attacker.
Edit : the context of the problem is HTML Video DRM as specified in EME specifications. There is a ClearKey api that is part of this standard and does nor require closed source plugin from WideVine or FairPlay etc. But as multiple responses have pointed out, ClearKey cannot be protected. (which unfortunately means using propritory DRM plugins).
You can not guarantee the security of any data once it reaches the client.
There is just no way to do this. Once the client receives this, especially if they also receive the decryption key, they have full access to all the secrets within.
On a very simple scale, they can just drop some breakpoint or put some prints in the javascript console. If they want to get more advanced they can use tools like wireshark to see the data as it comes over the wire.
Now if you want to send them encrypted data that doesn't get decrypted, and it is strongly encrypted, then its not as bad. But if you're never going to decrypt it on their side, then what are you even sending it for?
Agree that it can't be done. You could do it with asymmetric encryption. But I would go back to why you're doing it - if the connection were SSL encrypted, there is no reason to do it.
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.
I would like to write a JS function to have access from the browser to the public data stored on the hardware security token inserted in an USB port.
Specifically, in an intranet where ALL users have security tokens, I would like to have some sort of landing page, which will ask the user to enter his/her security token credentials (inserted in the USB port), and then read the public information from that token (I do not really need ALL of them, but I am interested mostly in the user name, certificate name(s) loaded in the token and their expiration date) and load them in the web page (to be displayed).
I have little to none experience with security devices like that, but I assume this is not a very complicated issue (though "googling" did not manage to get me in the right direction of how to make it work).
Thank you.
In my company we created a service installed installed in client's device, this service uses java to access the token and it provides an API(in client localhost), not sure if it's the best way but it works, if you find another way to solve this issue please leave a comment.
You can use the WinUSB API implemented in Chrome v54+.
You'll need to know the intrinsic structure of your USB token.
Theoretically JS runs in the browser, then after the first download can be easily copied and made to run directly from the local, without going through the remote server. Because I need to sell an application * js (pay-as-you-use) I need to check each request and make it available ONLY if required by that particular site and, of course, only if he paid.
It doesn't work. As soon as someone downloaded a copy of the JavaScript file, he or she can always save a copy of it and even redistribute it.
Thus you cannot protect the JavaScript itself - but assuming you rely on some client-server interaction (i.e. AJAX), the server would not respond to requests coming from non-authorized sources, thus rendering the client-side worthless.
If you need to protect your business logic, don't put it into JavaScript. Alternatively, sue everybody who uses your scripts without having obtained a license (not sure if this is practical, though ...).
I wouldn't make the JS file that you plan to sell available directly on a URL like
yourdomain.com/yourfile.js
I would offer it on a URL like
yourdomain.com/getfile
Where /getfile is a URL that is processed by a PHP/Java etc server-side language where you can check whatever credentials you need to check, be it requesting domain name, IP address, some token or something else.
if your application is made in java you can use a ServletFilter to check if the request is valid (if the IP is correct, or maybe you can use a ticket like the facebook, twitter, whatyouwant rest API), and if isn't valid don't show nothing
if you aren't using java I think that something similar can be made with every programming language
It may be a little more trouble than it's worth. Yes, you could require clients to provide a token and whitelist certain domains, etc. But they can still open any site that uses that particular JavaScript -- even someone else's -- and just Save As... .
A better bet is controlling the script's interaction with your server. If it makes any AJAX calls a server you control, then take that chance to authenticate. If it doesn't depend on data from you in that way, I think you'll just have to face the problem that anyone dedicated enough will be able to download your script and will be able to use it with a little bit of playing around.
Your best bet is, in addition to the above, keep track of domains that have paid and search every once in a while to find if anyone's taking your code.
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.