I noticed when looking at the templates for mvc internet applications the password is sent from the client to the server in plaintext, although I believe it is probably encrypted/hashed+salted when stored in the database.
Is the best thing to increase security here to enable SSL/HTTPS only or would it also be best to hash the password on the client side so it couldnt be intercepted en-route to the server or is this overkill?
Is there anything in the asp.net framework or 3rd party tools that would help with such a client side encryption/hashing?
The correct solution here is to use SSL encrypted page (and SSL post back - meaning post to the same ssl page, or to other ssl page)
If you try to encrypt it or hash it before send it with javascript you just make your code more complicate and not add so much to the security of it.
To say some more thinks, let say that some one in the middle get the post back values, then the hash of the password is usual 48 to 128 bit, less than the SSL security that have a key f 2048 bits. So no special gain if you hash the password before send it.
It came to my mind one more issue : if you make the hash of the password on client side then you expose your key, and if some one get your key, then can create from the hash, passwords that give the same hash. So do not make the hash/salt of your password on client because you have also a security issue.
Related
I want to encrypt the password sent from client side. I found crypto-js which provides AES implementation. My question is that if i use a "passphrase" for encryption, will anybody who can view the source of the page can also see my "passphrase" too ? If i have the wrong concept please help me clear it.
No, you cannot just read the password if it is not stored in JavaScript.
However, in almost any case where the JavaScript code can be read, the JavaScript code can also be changed. And if you cannot trust the code, then all bets are off - the password may be send to or retrieved from anywhere.
Take for instance an internet cafe. You connect to "coffeeplace.com" but you're actually logging on to a hoax service. In that case any unprotected connection can be altered. If the hoax service has obtained a rogue CA certificate then this is even true for HTTPS connections.
If you want to protect a password you should send it over a HTTPS connection. If you want application level security on top of the HTTPS transport security then you could encrypt the password using a public key; the server can then later decrypt it with a private key.
Application level security is useful if you want to store the password (hash) securily on your servers for instance. You could then later process the encrypted password using a service in the back-end.
To answer your actual question: Yes, everyone will see the passphrase.
But really, do some research on:
password hashing: Do you really need to know the plain text of user's passwords?
why using javascript for crypto is a really bad idea in almost all use cases.
Information security in it's whole
or please leave information security to people who know their turf. You are quite probable to introduce new problems, because crypto is hard, even with all the best intentions.
I'm trying to understand something. When I implement PBKDF2 in a server and client, it is my understanding (could be way wrong, sorry), that the server keeps the encrypted/hashed password in the database, and the user sends his or her password over the net and then it is checked by the server for validity.
What Im curious about is, exactly how do I prevent the users submission over the net to be seen and the users password exposed? do I Just depend on the networking library or SSL to protect this information?
How do i make sure the the password that's being sent over the net is in a way that cannot be exposed easily, but can still be read by the server to check against the hash?
Would it be wise to perform an SHA2 hash on the password client side, and then send that to the server and then check the sha2 has against the PBKDF2 hash? The server will never really even know the users password, the only possible recovery option is to reset it. Is this type of system acceptable?
What kinds of these things are done normally by the professionals?
When I implement PBKDF2 in a server and client, it is my understanding (could be way wrong, sorry), that the server keeps the encrypted/hashed password in the database, and the user sends his or her password over the net and then it is checked by the server for validity.
This is basically correct. When setting up an account the user sends user and pass to the server. The server stores user and PBKDF2(pass) and then discards pass. When logging in the server looks up against the user column and compares PBKDF2(pass_as_submitted) to the value stored when the account was set up. If they match, the user is authenticated.
Do I just depend on the networking library or SSL to protect this information?
In the sort of situation you're talking about, yes.
Would it be wise to perform an SHA2 hash on the password client side, and then send that to the server and then check the sha2 has against the PBKDF2 hash?
No. The problem here is you're just changing the thing you're keeping from the user's password to a hash of the user's password. It's still known to an attacker who can read the database.
(There are reasons this is marginally better than knowing the password, most particularly in case of password reuse. However, these do not justify such an approach.)
It's worth pointing out as well that SHA2(password) will not match PBKDF2(password).
What kinds of these things are done normally by the professionals?
First, use TLS (aka SSL). Having a good, encrypted connection between client and server is first priority. For a website, you should use TLS on every page, not just when sending the password. At the very least it must be used on the login page and on the request that receives username and password information.
Your TLS connection should be set up properly: it should use HSTS if appropriate (and it's a website). It should avoid outdated algorithms (only support TLS 1.1+ if possible). It should use appropriate cipher modes.
Beyond that, it depends on your use case. Perhaps it's worth implementing two factor authentication - be it using TOTP or SMS codes or similar. Perhaps you should be looking at logins without passwords, for example using client-side TLS certificates or OAuth2 tokens. Maybe you should use an existing authentication library like Kerberos. Maybe you need to look at password policies to ensure users are setting good passwords or pass phrases.
These questions are complex and depend on your use case. Thinking about them is the big first step most people don't take. Using PBKDF2 is a great start but there's no universal answer. If possible, get an expert to do your security analysis. If not, open source plus some promo can often get people to look at it. Worst case scenario, read up on security, check out the OWASP Top 10 and think about every part of the system. Where possible use existing libraries made by experts. If you have to roll your own, you're probably doing it wrong.
I am considering installing SSL/TLS for my domain. There are two questions that have been bothering me:
Is there any scenario where a https connection can fallback to http? So, for e.g. if my ajax looks something like this
$.post("https://foo.com", function(){
});
Is there any chance this could change to
$.post("http://foo.com", function(){
});
and even if it does would my domain be still accesible at http://foo.com ?
Next I have read extensively about using SSL/TLS and from what I have read it seems to be fairly accurate to assume that if I have this enabled and even if I send the user credentials in plain text, it's still secure (There would be encryption with salt and everything on the server of course). To what extent is this true and would creating a hash on the client and then sending it over https be any more secure?
Update: If sending plaintext over SSL is secure enough, then what really is the point of using things like cnonce ? Isn't it just unnecessary overhead on the client?
No, HTTPS never falls back to HTTP automatically. It would take deliberate action by the user. If you're just going to a web page by putting its URL into the address bar, this is easy; for form submission it's harder.
Yes, sending plain text over SSL is fine. In fact, sending a hashed password doesn't really increase security much at all -- if someone manages to sniff the connection and gets the hashed password, that's all they need to be able to login to the site. It has one small advantage: if the user uses the same password at multiple sites, learning the hashed password for one site doesn't help them get into another site that uses a different (or no) hash. And it's not likely to be feasible to send salted hashes, since the client doesn't know the salt.
A cnonce adds an extra level of protection. If, somehow, someone manages to crack the SSL encryption, the cnonce prevents them from getting a usable password from it. This basically addresses the point I made above about why sending a hashed password doesn't help: what you need is something that changes from session to session, and a cnonce provides this.
See https://security.stackexchange.com/questions/3001/what-is-the-use-of-a-client-nonce
How to Encrypt Client side login before sending to server ?
You should use HTTPS.
Building security by yourself is hard, and you are very likely to get it wrong.
You should stick with the systems that the experts use.
On the server, remember to hash and salt the passwords, preferably using bcrypt.
There's one very simple solution. SSL. Ensure that all your login activities are served via https:// URLs.
The way that you do this, at least the "setting the server up" part vary depending on what web server you're using. You'd be better off asking a question of that nature on http://www.serverfault.com/
You can only use https - any client side encryption would be viewable on the client and therefore useless. There is SO question on this: password encryption at client side
You should really use HTTPS, but if you can't use HTTPS then the alternative is to create a hash.
Server generates a random 'salt' for the session
JavaScript on client-side creates a cryptographically secure hash of the user's password and the salt.
Hash is sent to the server, you can then retrieve the password from the database, create a hash using the salt for the session and the password from the DB and check if it is the same as the one sent from the client. - If it is then the password is a match.
An example of using JavaScript to protect passwords: http://pajhome.org.uk/crypt/md5/auth.html
Imagine that you have a simple site with only 2 pages: login.aspx and secret.aspx. Your site is secured using nothing but ASP.net forms authentication and an ASP.net Login server control on login.aspx. The details are as follows:
The site is configured to use the SqlMembershipProvider
The site denies all anonymous users
Cookies are disabled
The are obviously many things to consider regarding security but I am more interested in the zero code out of box experience that comes with the .net framework.
If, for the sake of this question, the only attack points are the username/password textboxes in login.aspx, can a hacker inject code that will allow them to gain access to our secret.aspx page?
How secure is the zero code out-of-box experience that Microsoft provides?
You still have some variables that aren't accounted for:
Security into the data store used by your membership provider (in this case, the Sql Server database).
security of other sites hosted in the same IIS
general network security of the machines involved in hosting the site, or on the same network where the site is hosted
physical security of the machines hosting the site
Are you using appropriate measures to encrypt authentication traffic? (HTTPS/SSL)
Not all of those issues are MS specific, but they're worth mentioning because any of them could easily outweigh the issue you're asking about, if not taken care of. But, for the purpose of your question I'll assume there aren't any problems with them.
In that case, I'm pretty sure the forms authentication does what it's supposed to do. I don't think there's any currently active exploit out there.
As far as I know password will be sent as plain text (but encoded). So the most important thing to do is to use HTTPS protocol on login screens.
The other setting seems to be secure for me.
With HTTP Basic Authentication, which is what the .NET basic forms authentication is using, in order to view the secret.aspx page, the browser must send a Base64 encoded concatenation of the username and password.
Unless you utilize SSL, anyone who has access to scan the network between the server and the browser can read this information. They can decode the username and password. They can replay the username and password in the future to gain access to the secret.aspx page.
That said, unless you use SSL, someone can also scan the whole session of someone else using secret.aspx, so in effect, they would have access to the content of the page as well.
Well, try and look behind the scenes:
Password Protection
Applications that store user names,
passwords, and other authentication
information in a database should never
store passwords in plaintext, lest the
database be stolen or compromised. To
that end, SqlMembershipProvider
supports three storage formats
("encodings") for passwords and
password answers. The provider's
PasswordFormat property, which is
initialized from the passwordFormat
configuration attribute, determines
which format is used:
MembershipPasswordFormat.Clear, which stores passwords and password
answers in plaintext.
MembershipPasswordFormat.Hashed (the default), which stores salted
hashes generated from passwords and
password answers. The salt is a random
128-bit value generated by the .NET
Framework's RNGCryptoServiceProvider
class. Each password/password answer
pair is salted with this unique value,
and the salt is stored in the
aspnet_Membership table's PasswordSalt
field. The result of hashing the
password and the salt is stored in the
Password field. Similarly, the result
of hashing the password answer and the
salt is stored in the PasswordAnswer
field.
MembershipPasswordFormat.Encrypted,
which stores encrypted passwords and
password answers.
SqlMembershipProvider encrypts
passwords and password answers using
the symmetric encryption/decryption
key specified in the
configuration section's decryptionKey
attribute, and the encryption
algorithm specified in the
configuration section's
decryption attribute.
SqlMembershipProvider throws an
exception if it is asked to encrypt
passwords and password answers, and if
decryptionKey is set to Autogenerate.
This prevents a membership database
containing encrypted passwords and
password answers from becoming invalid
if moved to another server or another
application.
So the strength of your security (out of the box) will depend on which password protection format strategy you are using:
If you use clear text, it is obviously easier to hack into your system.
Using Encrypted on the other hand, security will depend on physical access to your machine (or at least, machine.config).
Using Hashed passwords (the default) will guarantee security depending on: a) known reversals of the hashing strategy of RNGCryptoServiceProvider class and b) access to the database to compromise the randomly generated salt.
I do not know if it is possible to use some sort of rainbow table hack into the default Hash-base system.
For more details, check out this link:
http://msdn.microsoft.com/en-us/library/aa478949.aspx
If configured correctly through the membership provider, you will have a adequate level of security. Outside of that, access to that page might be accessible through cannonical attacks, but that has to do with your general security. I gave a presentation on using the Security Enterprise Application Blocks. You might want to read up on those and look into that when implementing security on your site, and just be aware of common security threats. No site will ever be 100% unhackable, given that you are on an open shared network and total security would be an unplugged server locked in a safe guarded 24/7 by the military (around DoD "A" level security, based of Orange book). But the out of the box functionality of the Membership Providers (when configured correctly) will offer a good amount of security.
Edit: Yeah, I agree with the other comment that was made, HTTPS on at least the log in screens is a given, if you want to protect the username/passwords from packet sniffers and network monitors.
Asp.Net supports cookieless sessions, as this blog post shows. Instead of a session cookie, it uses an identifier in the url to track users.
I am not sure how secure this is, but I would think it is a secure as the difficulty to brute force the identity string.
It looks like it works more or less out of the box, however when redirecting a user and wanting to maintain session state you must include the session id. The blog post shows how to do that, as well as many other articles on the web.
Here are two good articles from Microsoft on the subject:
How To: Protect Forms Authentication in ASP.NET 2.0
INFO: Help Secure Forms Authentication by Using Secure Sockets Layer (SSL)
Cookies over URL is not secure enough, there are so many different problems with it (especially referrer leakage if you've got any) and usage of HTTPS.