Sign up ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

I know these sorts of questions come up, but I couldn't find a simple answer, most of the answers are "don't do that"

For play, I built myself a webapp, it uses sjcl to encrypt and decrypt notes on the client, whilst sending the encrypted form back to the server.

I am storing the key in local storage.

From my research, I am at risk from:

  1. Cross site scripting attacks (my application uses AJAX to send and receive the data from the server, I'm not sure if that is an attack vector).
  2. Local machine being hacked. At the moment the app can only be used on machines I have full control over, the moment I log in from a machine I do not control and type my key, that machine essentially has my key.
  3. Any type of flaw in local storage that lets a site from a different domain read the storage of other websites stored in the browser.

I am sure I have missed countless other attack vectors.

At first glance, I feel like it's impossible to design a client side encrypted note taking application that never sends the key to the server. With programming, there is almost always a way.

Is there a way I can make the app actually usable?

share|improve this question
3  
Can you trust that a proxy isn't changing the javascript code as it goes through the wire? Related on Security.SE Is client side encryption really better than server side?. The question at the heart of every security problem is 'how secure do you want it to be?' realizing that the more secure, the more complex, and the more expensive. –  MichaelT Nov 8 '14 at 3:17
    
@MichaelT, Would using SSL migrate that particular attack? –  Joseph Nov 8 '14 at 3:25
1  
No. You've still got the man in the middle available there if any of the preconditions of SSL are not valid. –  MichaelT Nov 8 '14 at 3:28
    
You can sort of avoid the MITM by sending a bootstrap page with far future expire headers which contains only the decryption logic and code to fetch an encrypted javascript bootstrap. Then as long as the initial download was secure, successive ones are as well. If you use HTML5 appcache for that initial bootstrap page, you can even guarantee that it doesn't get evicted from the cache (you can paint yourself into a nasty corner with far-future expiration and HTML5 appcache, but here it may be a benefit). –  Joeri Sebrechts Nov 10 '14 at 13:17

4 Answers 4

up vote 1 down vote accepted
+50

Basically, if the key is safe, the data is safe too (provided that its a good encryption algorithm and the key long enough, which I take as granted).

If I understood right, you only send encrypted data over the wire, not the key itself. If it's not the case, please discard this whole answer.

Assuming the key is never sent over the wire, the only way to compromise the data is to discover the key. This could happen if:

  • How the key is generated is predictible
  • Somebody having access to the file
  • A virus on the PC
  • DNS spoofing attacks (claiming to be your host/domain) -> Use TLS and certificates (see http://dev.w3.org/html5/webstorage/#privacy)
  • Exploiting a bug in some exotic browser/version (dunno if this already happenned, and if there are some vulnerability alerts or such)
  • ...is there anything else?

...perfect security is hard to achieve. But in your case, it seems an attacker must go to great length in order to hack it, or the user have a compromised machine from the start. Usually, the bottleneck is the user itself. ;)

share|improve this answer

In basic terms you assume, that if you encrypt data on client side (creating a token) and send token to server over HTTP, it will be secure - this is not true.

Hacker can get the token via network monitoring software (he does not need password) - that's it. Estimated time to bypass this is like less then 15 min.

share|improve this answer
    
The token is the encrypted data, so getting that doesn't matter right? The important thing to keep away from the hacker is the key, and that doesn't leave the client as it lives in local storage. But is that secure? –  Joseph Nov 10 '14 at 14:12
    
So if your application was internet bank your task would be to keep pin codes unknown? Because client information and money are not safe! I am told you that hacker does not need to know your pin in order to scrape CI and money. –  Margus Nov 10 '14 at 14:47

First, from what I understand, you don't show to user any data from other users, so you don't really have to worry about XSS. If you would show it, then you would have to make some countermeasures, such as character escaping (that actually should be used anyway). Hacked machine and browser security flaws are things you rather can't predict.

Second, the encryption thing you created doesn't really work. Sorry. Unless you are a genious with years of experience in security, but then you wouldn't need to ask this question. Among things that should be considered when designing encryption are:

  • Man in the Middle - can someone catch user's data by decrypting data from server on own machine and reencrypt them when sending to client? Attacker may simply ask real server for token, and when pretending to client that he is the server, he has the luxury to generate own set of keys/tokens, which will look as legit as original.
  • Network monitoring - are you sure you are not susceptible for instance to replay attack? Assume you order some items in some shop. If attacker records it and replays to the server, the same, encrypted data, will server detect it, or commit transaction again?
  • Key generation - are the keys you use completely random, or just predictably random? If attacker can generate the same set of keys your server stores, he doesn't even need to directly attack you, he can just sit back and other implications are pretty obvious. And believe me, standard random with time seed is very predictable.
  • Lots and lots more...

There are libraries like SSL that make this for you, made by people with years of experience and, as you probably realize, even they happen to mistakes, but nobody seems to be particularly eager to implement any alternative for some reason.

In case of security, the best option is to use checked and popular solutions, as they are probably also the most safe ones. As there is quite a few open-source and free libraries available, that should not be a problem. Ready encryption supported by browser will probably take care of more problems than you will ever probably imagine there is.

Unless of course I misunderstood you and you were not playing with webapps for webapp part of it, but for security thing. Then keep trying, and remember you will also learn a lot by attacking the app you created.

share|improve this answer

Don't do that.

OK, first of all you need to understand that even if you go to the ends of the Earth to make your application 'safe', it will never be safe. NEVER.

On a more positive note, let's go over what you could do to reduce the chances. I Googled sjcl and here I am assuming you mean the Stanford Javascrpit Crypto Library.

Whilst the SJCL is powerful on its own (with simple encrypt() and decrypt() methods), you may want to take control of it a bit more using its API.

After you've got that down, as mentioned in the comments, the most important question is really, how secure do you want it to be? From your question, quote:

For play, I built myself a webapp, it uses sjcl to ....

... which suggests to me that you probably aren't looking for a lot of security. But, I also presume that you are probably looking to prepare for a scenario in which you would need a lot of security.

I'm also assuming that the server wants nothing to do with the stuff the client enters.

One more point to keep in mind:

Quote from the link in first comment

... it's about perception. If your users perceive that their data is being treated in a secure manner, then they are likely to be more happy regardless of whether or not this is actually the case.

So, here are the possible options:

  • Use server-side encryption. This is the most obvious answer and will protect you from 99% of things that could happen. Even though the server would not need this data, it's still better to keep it somewhere on the network where the server can protect it. But here's the problem:

Today, many cloud service providers deliberately provide server-side security to maintain control. But server-side security requires trying to defend everywhere user data is stored: every disk, every server, every link, every router, and every database. Security is only as good as the weakest link, so it only takes one tiny mistake, vulnerability or mishandling for there to be a data breach.

  • Use a backend service. This has its own risks, like every other option you could possibly think of, because this really depends on who you want to trust (like every other thing you could possibly think of). There are actually two options in this case.

    • Whip up your own backend. Here I just gave you a good reference which you should be able to adapt to your needs. This is good option, and makes it really secure, but then again, your server would probably have to make sure this back-end is secure, and that probably creates more problems for you then it solves.
    • Use an existing back-end service. This is recommended, but the problem is which back-end should you use? After all, sending sensitive data to an unknown company is never safe. But I do know a few that are good. I would recommend backbeam.
  • Use SecureStore. I've seen many people using this (though never used it myself very much) and they say it yields great results. Basically, it involves not allowing data to stay on the disk forever, and controller encryption keys. More details can be found here.

Quote:

There are two major problem the data storage mechanism in localStorage:

  • The data is stored on unencrypted on disk. That means anyone with access to the computer can potentially get access to that data.
  • The data remains on disk until either the site removes it or until the user explicitly tells the browser to remove it. That means the data may remain on disk permanently otherwise.

                                     ...
    

    The proposal is based on a few simple concepts that are shared amongst security-conscious companies:

  • User data should not be stored on disk unencrypted.

  • Even when user data is stored encrypted, the company must control the encryption algorithm and key.
  • User data, even when encrypted, should not persist on disk forever.

In the end, whatever you decide to use will, once again, depend on two things:

  • Whom you trust, and
  • what level of security you want (you can never achieve 100%).

Summary

Here I've just summed everything up for reference.

Assumptions

Possible options (in short):

  • Server-side encryption: Rating - 3 / 5
  • Back-end, whether custom or existing: Rating - 4 / 5
  • SecureStore: Rating - 4.5 / 5
share|improve this answer
1  
IMHO your post doesn't answer how the client side encryption would be vulnerable. It basically says "do it on the server" but not why. How it would be possible for a third-party to retrieve the data in this scenario is the question of interest here. ...Assuming the client computer is not compromised. Otherwise, it's not safe anyway, and you can even intercept what you receive from the server. –  arnaud Nov 11 '14 at 16:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.