Security issues to consider?
August 25, 2013 2:06 PM Subscribe
I'm making a small app (website) that stores arbitrary encrypted data on a server. It's always encrypted on the server; encoding and decoding the information takes place in the browser via JS using the Stanford Javascript Crypto Library.
I'd like to avoid any serious security issues that are avoidable. Some stuff is beyond the scope of the app, like keyloggers. There's only so much I can do! But what is within the scope of the app that I need to be aware of?
Aside: I also think things like malicious code in a second browser tab somehow gaining access to keystrokes, or to the JS running in the app window, is a browser security issue and also beyond the scope of the app. Should I rethink that? Any steps to minimize danger from the browser's sandbox becoming compromised?
The primary use case is to provide quick and easy access to my passwords in an environment where I have access to the web, no ability to use KeePass, and a reasonable belief that the machine is free of malicious monitoring.
I'd like to avoid any serious security issues that are avoidable. Some stuff is beyond the scope of the app, like keyloggers. There's only so much I can do! But what is within the scope of the app that I need to be aware of?
Aside: I also think things like malicious code in a second browser tab somehow gaining access to keystrokes, or to the JS running in the app window, is a browser security issue and also beyond the scope of the app. Should I rethink that? Any steps to minimize danger from the browser's sandbox becoming compromised?
The primary use case is to provide quick and easy access to my passwords in an environment where I have access to the web, no ability to use KeePass, and a reasonable belief that the machine is free of malicious monitoring.
You've just dropped the equivalent of "I'd like to build a skyscraper with steel. What do I need to know?"
Listen, crypto is hard, and it's hard not because the math is crazy. It's hard because there are about half a billion different ways you can screw it up in the code wrapping the crypto functions. You need to better define your problem. Absent a better description of how you're encrypting, what you're encrypting, where you're sending it, what channels you're using, and how much risk you're willing to tolerate, you're really asking me to educate you on crypto engineering.
So, in light of that, go buy yourself a copy of Cryptography Engineering, read it cover to cover, and come back if you have more questions.
posted by bfranklin at 2:29 PM on August 25, 2013 [1 favorite]
Listen, crypto is hard, and it's hard not because the math is crazy. It's hard because there are about half a billion different ways you can screw it up in the code wrapping the crypto functions. You need to better define your problem. Absent a better description of how you're encrypting, what you're encrypting, where you're sending it, what channels you're using, and how much risk you're willing to tolerate, you're really asking me to educate you on crypto engineering.
So, in light of that, go buy yourself a copy of Cryptography Engineering, read it cover to cover, and come back if you have more questions.
posted by bfranklin at 2:29 PM on August 25, 2013 [1 favorite]
Good Brain's response is the one I was going to make: how will you ensure that the code being delivered to your browser is the code you intended? In your scenarios is it reasonable to trust that the server from which you serve the webapp has not been compromised to serve backdoored code?
There have been massive, acrimonious arguments about whether this kind of crypto-in-the-browser architecture is a good idea in the last few years, eg around CryptoCat. Their threat model is different from yours; it might be reasonable for you to do things that they shouldn't. But if I were you I'd consider the arguments against their setup carefully to see if they also apply to yours.
posted by hattifattener at 2:43 PM on August 25, 2013
There have been massive, acrimonious arguments about whether this kind of crypto-in-the-browser architecture is a good idea in the last few years, eg around CryptoCat. Their threat model is different from yours; it might be reasonable for you to do things that they shouldn't. But if I were you I'd consider the arguments against their setup carefully to see if they also apply to yours.
posted by hattifattener at 2:43 PM on August 25, 2013
The basic crypto algorithms are easy. Anybody can copy AES-256 out of a book and run some validation tests to make sure it's operating correctly. It's everything else (all the stuff you are proposing to invent from scratch) that makes crypto hard.
You should not do this.
posted by ryanrs at 2:44 PM on August 25, 2013
You should not do this.
posted by ryanrs at 2:44 PM on August 25, 2013
Response by poster: More specific threats would be helpful. Like, if there are a million? Just pick two. Just two. Thanks.
Please.
In your scenarios is it reasonable to trust that the server from which you serve the webapp has not been compromised to serve backdoored code?
Yes, it's reasonable to trust the server. Even if it were unreasonable, everything the client needs, including the JS, could be local files.
This is a lot like those questions people ask about processing credit cards (protip: don't). There are extremely good reasons you should not roll your own with these kinds of things, unless you are literally an expert in the field.
I think your analogy is erroneous. I'm not asking how to build Stripe (to continue the metaphor), I'm asking how best to use Strip to create a "buy now" button.
posted by jsturgill at 2:53 PM on August 25, 2013
Please.
In your scenarios is it reasonable to trust that the server from which you serve the webapp has not been compromised to serve backdoored code?
Yes, it's reasonable to trust the server. Even if it were unreasonable, everything the client needs, including the JS, could be local files.
This is a lot like those questions people ask about processing credit cards (protip: don't). There are extremely good reasons you should not roll your own with these kinds of things, unless you are literally an expert in the field.
I think your analogy is erroneous. I'm not asking how to build Stripe (to continue the metaphor), I'm asking how best to use Strip to create a "buy now" button.
posted by jsturgill at 2:53 PM on August 25, 2013
What protections do you put in place against replay attacks (if writes are allowed)? What protections against MITM? Against offline attacks on the data? Are you sure you configured SJCL to use password-safe encryption functions?
Etc., etc., etc.
posted by introp at 3:23 PM on August 25, 2013
Etc., etc., etc.
posted by introp at 3:23 PM on August 25, 2013
Response by poster: What protections do you put in place against replay attacks (if writes are allowed)? What protections against MITM?
Connection to the server will be encrypted. SSL protects against replay attacks and MITM, doesn't it? Attacks against SSL itself (compromises to a real CA or malware on the PC adding a bogus CA) seem like they are beyond the scope of the app.
Requests will also be hashed with a timestamp and a narrow window.
If the above is wrong, is there reading you could point me to? Please.
Against offline attacks on the data?
Could you elaborate? This is an attacker who has the encrypted data? Or physical access to the computer? How are they getting that?
OK so just to get the groundwork correct, are you saying you will store encrypted chunks of data on a server, deliver these as-is to a client browser, and then the browser will decrypt these chunks of data within Javascript code, operate on the un-encrypted data within Javascript, then re-encrypt them within Javascript before sending the now-encrypted data back to your server?
Where will the Javascript files be served from, specifically, and how are you managing keys?
Yeah, that's a good synopsis.
The JS will be served from a semi-private server; Amazon S3, a VPS on Linode, Google App Engine, or similar. Not a shared host. Is that not paranoid enough?
Before the data is sent to the browser, the user will have authenticated themselves to the server with something like Persona, OpenID, or their Google account.
Entering the actual key will be a second authentication step. The user will copy and paste it into the browser when prompted.
posted by jsturgill at 3:56 PM on August 25, 2013
Connection to the server will be encrypted. SSL protects against replay attacks and MITM, doesn't it? Attacks against SSL itself (compromises to a real CA or malware on the PC adding a bogus CA) seem like they are beyond the scope of the app.
Requests will also be hashed with a timestamp and a narrow window.
If the above is wrong, is there reading you could point me to? Please.
Against offline attacks on the data?
Could you elaborate? This is an attacker who has the encrypted data? Or physical access to the computer? How are they getting that?
OK so just to get the groundwork correct, are you saying you will store encrypted chunks of data on a server, deliver these as-is to a client browser, and then the browser will decrypt these chunks of data within Javascript code, operate on the un-encrypted data within Javascript, then re-encrypt them within Javascript before sending the now-encrypted data back to your server?
Where will the Javascript files be served from, specifically, and how are you managing keys?
Yeah, that's a good synopsis.
The JS will be served from a semi-private server; Amazon S3, a VPS on Linode, Google App Engine, or similar. Not a shared host. Is that not paranoid enough?
Before the data is sent to the browser, the user will have authenticated themselves to the server with something like Persona, OpenID, or their Google account.
Entering the actual key will be a second authentication step. The user will copy and paste it into the browser when prompted.
posted by jsturgill at 3:56 PM on August 25, 2013
There are many possible pitfalls in using JavaScript for encryption. Make sure you understand them and can say with confidence which ones do or do not apply to your application. This slide deck has an overview of more potential problems.
In particular, you should ask whether the client-side encryption prevents any attack scenarios that SSL/TLS does not already prevent. And if you do decide that JS crypto is the right solution, be very careful when choosing which implementation to use.
posted by mbrubeck at 3:57 PM on August 25, 2013
In particular, you should ask whether the client-side encryption prevents any attack scenarios that SSL/TLS does not already prevent. And if you do decide that JS crypto is the right solution, be very careful when choosing which implementation to use.
posted by mbrubeck at 3:57 PM on August 25, 2013
Aside from specific issues related to JS crypto, you'll need to worry about the same security issues as every web developer. For example, neither JS crypto nor SSL will prevent attackers from exploiting XSS or CSRF bugs in your application or its dependencies, or generic attacks like clickjacking.
In addition to carefully auditing everything for those and other vulnerabilities, you can take advantage of newer browser features designed to mitigate them like CSP, httponly, X-Frame-Options, and STS.
posted by mbrubeck at 4:15 PM on August 25, 2013
In addition to carefully auditing everything for those and other vulnerabilities, you can take advantage of newer browser features designed to mitigate them like CSP, httponly, X-Frame-Options, and STS.
posted by mbrubeck at 4:15 PM on August 25, 2013
Sorry for spamming this thread, but hopefully the comments are still useful.
This also sounds like an application where BREACH is a concern. You should disable HTTP compression in your web server unless you have some other reason to believe that your app is immune.
posted by mbrubeck at 4:22 PM on August 25, 2013
This also sounds like an application where BREACH is a concern. You should disable HTTP compression in your web server unless you have some other reason to believe that your app is immune.
posted by mbrubeck at 4:22 PM on August 25, 2013
Could you elaborate? This is an attacker who has the encrypted data? Or physical access to the computer? How are they getting that?
you haven't told us your threat model, so we don't know who you're trying to secure your data against. perhaps they got it with a subpoena, perhaps they exploited a vulnerability in your app. if you're concerned enough to want to keep the server-side data encrypted, you must be assuming the data could be compromised.
SSL protects against replay attacks at the SSL layer, but not at the application layer. your timestamp idea looks like an attempt to do application layer checking, but there are a million ways to get it wrong. for example, how does it stand up in the face of an attacker who can change the client clock? what if they can change the server clock? (again, encrypting the server-side data implies an attacker who can compromise the server)
posted by russm at 4:33 PM on August 25, 2013 [1 favorite]
you haven't told us your threat model, so we don't know who you're trying to secure your data against. perhaps they got it with a subpoena, perhaps they exploited a vulnerability in your app. if you're concerned enough to want to keep the server-side data encrypted, you must be assuming the data could be compromised.
SSL protects against replay attacks at the SSL layer, but not at the application layer. your timestamp idea looks like an attempt to do application layer checking, but there are a million ways to get it wrong. for example, how does it stand up in the face of an attacker who can change the client clock? what if they can change the server clock? (again, encrypting the server-side data implies an attacker who can compromise the server)
posted by russm at 4:33 PM on August 25, 2013 [1 favorite]
More specific threats would be helpful. Like, if there are a million? Just pick two. Just two. Thanks
We can't give you two because you aren't giving us enough info to determine which two are applicable.
If the above is wrong, is there reading you could point me to? Please.
Cryptography Engineering. Seriously, it is clear to pretty much everyone commenting here that you are way out of your depth -- you're handwaving over what security features SSL provides, but you're trying to build a secure app! Do the 101 reading, or put together an architecture diagram and a data flow diagram so we can figure out which questions you should be asking.
posted by bfranklin at 5:53 PM on August 25, 2013 [1 favorite]
We can't give you two because you aren't giving us enough info to determine which two are applicable.
If the above is wrong, is there reading you could point me to? Please.
Cryptography Engineering. Seriously, it is clear to pretty much everyone commenting here that you are way out of your depth -- you're handwaving over what security features SSL provides, but you're trying to build a secure app! Do the 101 reading, or put together an architecture diagram and a data flow diagram so we can figure out which questions you should be asking.
posted by bfranklin at 5:53 PM on August 25, 2013 [1 favorite]
In the end if you're just wanting to protect your passwords from snooping by your housemate or in case someone who steals your laptop, then you can do pretty much whatever you want. Those adversaries presumably aren't going to have the knowledge or incentive to break whatever you build. But if you're planning on having other people use it, and who knows, perhaps it'll get popular, then you really need to be clear about what threats you're claiming to protect the data against, and have more of an understanding of security engineering than you've demonstrated here (that's not a slam on you - security engineering is hard, and at least you've started by asking "what do I need to know?" rather than just jumping in and implementing something).
Some possible starting points are the Google Code University Web Application Exploits and Defenses lab, perhaps the Crypto 1 subject at Coursera, and Schneier's Cryptography Engineering (mentioned by bfranklin upthread). There's a couple of other web app security courses that would probably help, but whose names escape me at the moment. I'll see if I can find the links.
posted by russm at 5:58 PM on August 25, 2013
Some possible starting points are the Google Code University Web Application Exploits and Defenses lab, perhaps the Crypto 1 subject at Coursera, and Schneier's Cryptography Engineering (mentioned by bfranklin upthread). There's a couple of other web app security courses that would probably help, but whose names escape me at the moment. I'll see if I can find the links.
posted by russm at 5:58 PM on August 25, 2013
There are a lot of little things in your description and questions that are setting off alarm bells for a lot of us. It's probably hard to grok the level of incredulity / hostility given where you are standing.
Let me throw out a tiny counter-example: if you're assuming that your server can't be compromised and you can trust the client computer (which are huge parts of your above questions/replies), why not just store a passwords in plaintext there and use the existing web infrastructure to limit access? You don't serve up the file unless they've connected over HTTPS and have satisfied the web server with a password. This takes no more work than placing the password file, setting your .htaccess or equivalent, and generating a username-password pair there on the server.
If you can explain why that isn't secure enough without explaining why your proposed solution isn't also insecure (on some levels), you're likely going to get a lot of either head-scratching or face-palming. You've moved part of the security problem from one machine to another, without either moving all of it (leaving the server still almost entirely vulnerable) or explaining why your partial solution is reasonable given the attack/cost/whatever model.
posted by introp at 6:42 PM on August 25, 2013 [2 favorites]
Let me throw out a tiny counter-example: if you're assuming that your server can't be compromised and you can trust the client computer (which are huge parts of your above questions/replies), why not just store a passwords in plaintext there and use the existing web infrastructure to limit access? You don't serve up the file unless they've connected over HTTPS and have satisfied the web server with a password. This takes no more work than placing the password file, setting your .htaccess or equivalent, and generating a username-password pair there on the server.
If you can explain why that isn't secure enough without explaining why your proposed solution isn't also insecure (on some levels), you're likely going to get a lot of either head-scratching or face-palming. You've moved part of the security problem from one machine to another, without either moving all of it (leaving the server still almost entirely vulnerable) or explaining why your partial solution is reasonable given the attack/cost/whatever model.
posted by introp at 6:42 PM on August 25, 2013 [2 favorites]
Response by poster: why not just store a passwords in plaintext there and use the existing web infrastructure to limit access? You don't serve up the file unless they've connected over HTTPS and have satisfied the web server with a password. This takes no more work than placing the password file, setting your .htaccess or equivalent, and generating a username-password pair there on the server.
If you can explain why that isn't secure enough without explaining why your proposed solution isn't also insecure (on some levels), you're likely going to get a lot of either head-scratching or face-palming. You've moved part of the security problem from one machine to another, without either moving all of it (leaving the server still almost entirely vulnerable) or explaining why your partial solution is reasonable given the attack/cost/whatever model.
Could you explain how using JS to decode text in the browser would be less secure than viewing a text file in the browser?
The threat model is: I don't learn anything by uploading a text file to my server and securing the directory with htpasswd.
And I did describe a my particular use scenario previously. Almost everything I intend to store will be complex passwords so that I can access them on a machine that is secure but I don't have admin rights to and cannot install KeePass onto. I have zero interest in being able to outsmart the NSA or potentially obstruct a lawful subpoena, nor do I have any particular concern about my use on the machine being snooped on. I do have some amount of interest in creating a secure system that doesn't leak information given two broad assumptions: a reasonably secure server and a reasonably secure client.
I'm gone for the night; I hope to be around tomorrow to respond further. Thank you for providing actual scenarios and potential issues.
posted by jsturgill at 7:09 PM on August 25, 2013
If you can explain why that isn't secure enough without explaining why your proposed solution isn't also insecure (on some levels), you're likely going to get a lot of either head-scratching or face-palming. You've moved part of the security problem from one machine to another, without either moving all of it (leaving the server still almost entirely vulnerable) or explaining why your partial solution is reasonable given the attack/cost/whatever model.
Could you explain how using JS to decode text in the browser would be less secure than viewing a text file in the browser?
The threat model is: I don't learn anything by uploading a text file to my server and securing the directory with htpasswd.
And I did describe a my particular use scenario previously. Almost everything I intend to store will be complex passwords so that I can access them on a machine that is secure but I don't have admin rights to and cannot install KeePass onto. I have zero interest in being able to outsmart the NSA or potentially obstruct a lawful subpoena, nor do I have any particular concern about my use on the machine being snooped on. I do have some amount of interest in creating a secure system that doesn't leak information given two broad assumptions: a reasonably secure server and a reasonably secure client.
I'm gone for the night; I hope to be around tomorrow to respond further. Thank you for providing actual scenarios and potential issues.
posted by jsturgill at 7:09 PM on August 25, 2013
Could you explain how using JS to decode text in the browser would be less secure than viewing a text file in the browser?
The point isn't that it's less secure, rather that it is (depending on a bunch of other things) no more secure. If you can trust the server to provide unadulterated JS crypto libraries, and you can trust SSL to protect all your data in transit, and your application isn't vulnerable to remote compromise, then there's no need to encrypt the server-side data.
If your goal is "creating a secure system that doesn't leak information given two broad assumptions: a reasonably secure server and a reasonably secure client", and you're excluding the NSA, lawful subpoena, client-side exploits, and CA exploits from your threat model, then there's no need for any crypto beyond SSL.
introp's question boils down to "In what way do you see a regular web application with no client-side crypto as less secure than your proposed model?"
posted by russm at 7:22 PM on August 25, 2013 [1 favorite]
The point isn't that it's less secure, rather that it is (depending on a bunch of other things) no more secure. If you can trust the server to provide unadulterated JS crypto libraries, and you can trust SSL to protect all your data in transit, and your application isn't vulnerable to remote compromise, then there's no need to encrypt the server-side data.
If your goal is "creating a secure system that doesn't leak information given two broad assumptions: a reasonably secure server and a reasonably secure client", and you're excluding the NSA, lawful subpoena, client-side exploits, and CA exploits from your threat model, then there's no need for any crypto beyond SSL.
introp's question boils down to "In what way do you see a regular web application with no client-side crypto as less secure than your proposed model?"
posted by russm at 7:22 PM on August 25, 2013 [1 favorite]
I think your basic architectural idea makes sense for your use case. The main alternative I see would be to submit the encryption key/passphrase over SSL to the server, do encryption/decryption in memory on the server, and send the stored passwords over SSL between the client and the server.
As long as you never save the encryption key or the decrypted passwords to disk on the server, this gives the same basic security properties as your concept. In both cases, someone who just seized the server hard drives would have only the encrypted data, but someone who could modify the server or its traffic while the service is still running would be able to steal passphrases from users who connect after that.
The advantage to doing encryption in memory on the server are that you have access to implementations that are much better audited, tested, and hardened than any of the available JavaScript libraries. For example, well-regarded crypto implementations are hardened against side-channel attacks. The links I gave above explain some of the reasons this is hard to do in JavaScript.
A side channel attack is where you indirectly infer something about the internal state of the crypto code by observing how long it takes to run, how much memory it consumes, or other such effects. Practical side-channel attacks have been demonstrated many times. I'm not aware of any specific exploits using side-channel attacks against JavaScript crypto libraries, but if you are worried about attacks from code in another tab then this is one of the things I would worry about.
If this is purely for learning and personal use and you are not expecting it to withstand a determined expert attacker, then I think you're fine. Learn away!
posted by mbrubeck at 7:36 PM on August 25, 2013 [1 favorite]
As long as you never save the encryption key or the decrypted passwords to disk on the server, this gives the same basic security properties as your concept. In both cases, someone who just seized the server hard drives would have only the encrypted data, but someone who could modify the server or its traffic while the service is still running would be able to steal passphrases from users who connect after that.
The advantage to doing encryption in memory on the server are that you have access to implementations that are much better audited, tested, and hardened than any of the available JavaScript libraries. For example, well-regarded crypto implementations are hardened against side-channel attacks. The links I gave above explain some of the reasons this is hard to do in JavaScript.
A side channel attack is where you indirectly infer something about the internal state of the crypto code by observing how long it takes to run, how much memory it consumes, or other such effects. Practical side-channel attacks have been demonstrated many times. I'm not aware of any specific exploits using side-channel attacks against JavaScript crypto libraries, but if you are worried about attacks from code in another tab then this is one of the things I would worry about.
If this is purely for learning and personal use and you are not expecting it to withstand a determined expert attacker, then I think you're fine. Learn away!
posted by mbrubeck at 7:36 PM on August 25, 2013 [1 favorite]
The threat model is: I don't learn anything by uploading a text file to my server and securing the directory with htpasswd.Okay, now we're getting somewhere. :)
Making a toy educational app is a completely understandable thing, but I totally, totally did not get that from the original question. I've written such things myself, including something that sounds remarkably similar to what you've described. Unfortunately, you're asking something along the lines of the "I'm going to build a house; what are the structural things I need to look out for" question. That is, you're asking for a course on the state of the art, which is beyond the scope of an AskMe. You could probably spend a thousand hours on browser/server/Internet security and still not be an expert. If you have specific concerns, like how to choose the number of rounds of PBKDF, etc., or even much more basic questions like why choose PBKDF over generic cipher X, we can totally help you break those down and answer them. Otherwise we're throwing darts at an extremely large, target-rich board.
I recommend, as mentioned above by others, that you pick up Schneier's Cryptography Engineering, read it, and fan out from there. (I'm actually a big fan of his two previous, Practical Crypto and Applied Crypto, but they're starting to show their age a bit, especially Applied.) Good crypto is Hard, and the second step is learning that you don't even know what you don't know.
posted by introp at 7:37 PM on August 25, 2013
Oh, I should emphasize that the crypto is only one link here. If I were trying to attack your application, I'd start by ignoring the crypto completely and just look for classic web vulnerabilities like XSS that would let me pull the passwords out of the client after they are decrypted and being displayed to the user (or get the passphrase out of the client as the user types it in). So in addition to avoiding any holes in the crypto, you also need to avoid any holes in your HTML rendering, server configuration, etc.
posted by mbrubeck at 7:43 PM on August 25, 2013
posted by mbrubeck at 7:43 PM on August 25, 2013
Response by poster: If you can trust the server to provide unadulterated JS crypto libraries, and you can trust SSL to protect all your data in transit, and your application isn't vulnerable to remote compromise, then there's no need to encrypt the server-side data.
If your goal is "creating a secure system that doesn't leak information given two broad assumptions: a reasonably secure server and a reasonably secure client", and you're excluding the NSA, lawful subpoena, client-side exploits, and CA exploits from your threat model, then there's no need for any crypto beyond SSL.
introp's question boils down to "In what way do you see a regular web application with no client-side crypto as less secure than your proposed model?"
Things that might be gained by having it encrypted on the server:
----
Things I've seen mentioned:
XSS
There will be nothing user-submitted that will show up on the page aside from their login name and their secrets, both of which will be escaped before being inserted into the HTML. There's no need to have any unescaped user-submitted information. No information submitted via a GET variable will be stored or displayed in any way. No user submitted information will be inserted into a URL or attribute or any other context but HTML.
What else should I consider about XSS?
CSRF
Valid requests that have side effects will be signed with a timestamped hash and will use a verb other than GET.
What else should I consider about CSRF?
Clickjacking
I'll attempt to limit external shenanigans by including framekiller code on the site and an X-Frame-Options header set to DENY.
What else should I consider about clickjacking?
Replay attacks
SSL + hashed signatures that include a timestamp and a small window of validity (a few seconds, maybe).
SSL protects against replay attacks at the SSL layer, but not at the application layer. your timestamp idea looks like an attempt to do application layer checking, but there are a million ways to get it wrong. for example, how does it stand up in the face of an attacker who can change the client clock? what if they can change the server clock? (again, encrypting the server-side data implies an attacker who can compromise the server)
If they can change the server clock then I'm not worried about it. If they have that level of control over the server and are malicious (or have a court order) they can alter the JS sent to the client, no?
The timestamp will be relative to the server time.
What else should I consider about replay attacks?
Man in the Middle
This will be hosted on a non-shared server that allows for SSL connections. I'll be using a cheap certificate from a CA accepted by Google checkout.
Note that I'm not planning to do anything with Google checkout; just providing it as a list of CAs that someone in tech concerned with security thinks are acceptable, which should also be sufficient for my purposes.
HTTP requests will be redirected to HTTPS. HTTPS replies from the server will include a Strict-Transport-Security header.
What else should I consider about MITM attacks?
BREACH
TLS and HTTP compression will be turned off for the site.
What else should I consider about BREACH attacks?
Additional notes
The session ID cookie will be transmitted only over HTTPS.
There won't be any external images, CSS, or JavaScript. Everything will be loaded from the server. No ads. No CDN for the files. Probably going to use jQuery and Bootstrap.
What else should I plan on doing?
posted by jsturgill at 11:29 AM on August 26, 2013
If your goal is "creating a secure system that doesn't leak information given two broad assumptions: a reasonably secure server and a reasonably secure client", and you're excluding the NSA, lawful subpoena, client-side exploits, and CA exploits from your threat model, then there's no need for any crypto beyond SSL.
introp's question boils down to "In what way do you see a regular web application with no client-side crypto as less secure than your proposed model?"
Things that might be gained by having it encrypted on the server:
- Modest protection from low-level snooping employees at the hosting company. I'm sure Linode employees have never just trawled through my server and looked at files for no reason, but I'm also sure that they have that ability.
- Modest protection from a backup of the database being lost, stolen, or improperly disposed of and then looked through.
- Modest protection from idle snooping if the data or backups of it are seized for an unrelated reason. (My backup and Joe Blow's backup are on the same drive; the entire drive is seized because Joe Blow looked at kiddie porn; no one cares about my data on the drive anyway)
- My brother or a friend could use the system secure in the knowledge that I can't just run a query and see what they're storing; I'd have to be much more actively malicious rather than simply curious to an unethical extent in order to get a peek. (Locks are for honest people, right?)
- As mentioned before, the exercise of building it.
----
Things I've seen mentioned:
XSS
There will be nothing user-submitted that will show up on the page aside from their login name and their secrets, both of which will be escaped before being inserted into the HTML. There's no need to have any unescaped user-submitted information. No information submitted via a GET variable will be stored or displayed in any way. No user submitted information will be inserted into a URL or attribute or any other context but HTML.
What else should I consider about XSS?
CSRF
Valid requests that have side effects will be signed with a timestamped hash and will use a verb other than GET.
What else should I consider about CSRF?
Clickjacking
I'll attempt to limit external shenanigans by including framekiller code on the site and an X-Frame-Options header set to DENY.
What else should I consider about clickjacking?
Replay attacks
SSL + hashed signatures that include a timestamp and a small window of validity (a few seconds, maybe).
SSL protects against replay attacks at the SSL layer, but not at the application layer. your timestamp idea looks like an attempt to do application layer checking, but there are a million ways to get it wrong. for example, how does it stand up in the face of an attacker who can change the client clock? what if they can change the server clock? (again, encrypting the server-side data implies an attacker who can compromise the server)
If they can change the server clock then I'm not worried about it. If they have that level of control over the server and are malicious (or have a court order) they can alter the JS sent to the client, no?
The timestamp will be relative to the server time.
What else should I consider about replay attacks?
Man in the Middle
This will be hosted on a non-shared server that allows for SSL connections. I'll be using a cheap certificate from a CA accepted by Google checkout.
Note that I'm not planning to do anything with Google checkout; just providing it as a list of CAs that someone in tech concerned with security thinks are acceptable, which should also be sufficient for my purposes.
HTTP requests will be redirected to HTTPS. HTTPS replies from the server will include a Strict-Transport-Security header.
What else should I consider about MITM attacks?
BREACH
TLS and HTTP compression will be turned off for the site.
What else should I consider about BREACH attacks?
Additional notes
The session ID cookie will be transmitted only over HTTPS.
There won't be any external images, CSS, or JavaScript. Everything will be loaded from the server. No ads. No CDN for the files. Probably going to use jQuery and Bootstrap.
What else should I plan on doing?
posted by jsturgill at 11:29 AM on August 26, 2013
HTTP requests will be redirected to HTTPS.
Only if no information (e.g., POST values) is passed from HTTP to HTTPS. See Troy Hunt.
What else should I consider about MITM attacks?
I'd be hardening this with mutual authentication, but then you need to port a client certificate around.
The session ID cookie will be transmitted only over HTTPS.
Make sure that the cookie is marked as HTTPOnly as well as secure. There's no reason for Javascript to be touching your session cookie.
What else should I plan on doing?
Since this is an educational app and mostly in Javascript? Don't submit the password in the clear over the SSL channel. There are plenty of known issues with challenge/response protocols, but they can actually provide an additional modicum of defense when employed in transmitting the password field of a login page. I'd like to see more libraries offering this feature.
Make sure you disable autocomplete on all your fields and on the form itself (Firefox is touchy about the latter).
posted by bfranklin at 11:49 AM on August 26, 2013
Only if no information (e.g., POST values) is passed from HTTP to HTTPS. See Troy Hunt.
What else should I consider about MITM attacks?
I'd be hardening this with mutual authentication, but then you need to port a client certificate around.
The session ID cookie will be transmitted only over HTTPS.
Make sure that the cookie is marked as HTTPOnly as well as secure. There's no reason for Javascript to be touching your session cookie.
What else should I plan on doing?
Since this is an educational app and mostly in Javascript? Don't submit the password in the clear over the SSL channel. There are plenty of known issues with challenge/response protocols, but they can actually provide an additional modicum of defense when employed in transmitting the password field of a login page. I'd like to see more libraries offering this feature.
Make sure you disable autocomplete on all your fields and on the form itself (Firefox is touchy about the latter).
posted by bfranklin at 11:49 AM on August 26, 2013
Things that might be gained by having it encrypted on the server:
Fair enough, and as a learning project that's reasonable. Still, all but the learning exercise criteria could be met by doing the crypto in your app rather than at the client, which I'd argue is probably a better real-world design given your security criteria. (Not saying "don't do it your way", just something to keep in mind when you're working on systems with a security focus)
HTTP requests will be redirected to HTTPS.
I would not allow any requests that arrive over HTTP to ever reach the app at all, in any way. Have it plumbed to an HTTPS-only listener, with a distinct HTTP listener that serves a static redirect to the root of the HTTPS app.
posted by russm at 5:23 PM on August 26, 2013
Fair enough, and as a learning project that's reasonable. Still, all but the learning exercise criteria could be met by doing the crypto in your app rather than at the client, which I'd argue is probably a better real-world design given your security criteria. (Not saying "don't do it your way", just something to keep in mind when you're working on systems with a security focus)
HTTP requests will be redirected to HTTPS.
I would not allow any requests that arrive over HTTP to ever reach the app at all, in any way. Have it plumbed to an HTTPS-only listener, with a distinct HTTP listener that serves a static redirect to the root of the HTTPS app.
posted by russm at 5:23 PM on August 26, 2013
Response by poster: I would not allow any requests that arrive over HTTP to ever reach the app at all, in any way. Have it plumbed to an HTTPS-only listener, with a distinct HTTP listener that serves a static redirect to the root of the HTTPS app.
Is using Apache's mod_rewrite to redirect all requests to HTTPS not secure enough in this scenario?
posted by jsturgill at 6:13 PM on August 26, 2013
Is using Apache's mod_rewrite to redirect all requests to HTTPS not secure enough in this scenario?
posted by jsturgill at 6:13 PM on August 26, 2013
If you're fronting with apache, mod_rewrite is all good. I meant more to not do the HTTP -> HTTPS redirect inside your app, and to not pass any state through the redirect.
posted by russm at 11:58 PM on August 26, 2013
posted by russm at 11:58 PM on August 26, 2013
This thread is closed to new comments.
Beyond that, look for critiques of LastPass (which already does what you want).
posted by Good Brain at 2:21 PM on August 25, 2013