ASP.NET security provider is stuck storing passwords in plaintext - asp.net

I'm writing a small web app for intranet use, which was originally going to use Windows authentication. As such, I set up a few dummy users in Forms mode for testing and had the passwordFormat set to Clear for my own ease of use.
Now, for various reasons, we're not going to use Windows authentication anymore (going back to Forms authentication and the ASP.NET Membership provider) so I would like to enable password hashing or encryption so the passwords are more secure. I've changed this in the web.config file, but anytime I create a new user or update an existing user's password, the passwords are still storing in plaintext. This is happening whether I make these changes through the application (using the built-in management forms) or if I run the provider's stored procedures directly in the database (setting the appropriate #PasswordFormat variable, of course). In other apps where I've left the format on the default of Hashed, the hashing takes place automatically, so I'm very perplexed by this behavior.
Is there a way to get this back to hashing the passwords before storing? Or is this one of those "once you turn it on, you're stuck" kind of situations?

Related

Retroactively encrypting/hashing stored (plaintext) user credentials

I am currently working on a project in which I am rewriting an old (late 1990s) web application in ASP.NET. Part of this application is a user authentication system, which is used to access a couple of pages on the site. The user credentials (username, password, etc.) are stored in a database table.
This is all pretty standard, but while working with this database I found, to my horror, that this data is stored in plaintext.
I am wondering what the best way would be to improve the security of this insecure system. Is there an easy method of taking the plaintext data, encrypting (or hashing) it, and reinserting it? Can I use .NET Forms Authentication to facilitate any of this, and is it a good option for user authentication in the new app?
Thanks!
If you are on a Windows network, I'd use Windows Auth, which uses Active Directory. That would allow your Systems Admin group/person to administer who has access to the application.
Forms Auth is a good idea if Windows Auth won't work for you.
If they won't give you the time to implement either of the auth frameworks, I'd definitely encrypt the passwords on the database. Write a Console app and encrypt the passwords using information found here: Encrypt and decrypt a string
Then you'd need to modify your existing app to check encrypted passwords instead of plaintext ones.

Is there any way I can maintain password history of a user in ASP.Net application?

I need to view users password history in an ASP.net application.
Is there any way to achieve it?
You have to maintain that as an encrypted string in your backend. Meaning in the database or some file system (not recommended).
It depends.
In fact, storing plain passwords is the worst approach in terms of security.
Administrator must not have access to plain passwords, this the reason of most of applications prompts you to create a new one, because passwords are hashed and hashing prevents from reverting to plain text.
If you need to track passwords, you'll need to write a custom membership provider tracking them.
There is nothing built into .Net that will provide this information. You would have to write your own solution to create an audit trail of passwords but this would involve storing passwords in a visible format. Remember the massive caveat about plain passwords though!
So long as you're only doing this for old passwords i.e. storing them AFTER the user has set a new password it should be ok.

Implementing application security - App Level & DB level (ASP .NET & SQL Server 08)

I am about to deploy an ASP .NET application (developed with LINQ-to-SQL).
I have taken following precautions:
Database access via user with limited access, however, since application is to access the sensitive data, I can't deprive this limited access user from it
Database server is not exposed to external network - is hiding behind DMZ and all external ports are blocked
I have done thorough security testing of the web-application; SQL Injections, rights management, illegal data access (via post/get data tempering)
Application is operating on SSL
Questions:
1 - I am using ASP .NET authorization API; any recommendation for avoiding session hijacking (in case someone some-how gets to know the session key). Is there are way to change the authentication cookie less prone to threats? Say like, changing it after every request? (I know I am get very conscious about this particular item)
2 - Data in the database is not encrypted. To make things ultra-secure, I am thinking about implementing transparent data encryption. Can someone share his/her experience or a link about implementing data level encryption with SQL Server 2008 along with pros-and-cons?
3 - Recommendation for storing connection string in web.config. Is using integrated security better then using encrypted database connection string?
It's seems to me that it's enough of standard asp.net api for this task. There is a very good article from MS P&P team about securing your forms authentication, it should help you.
I don't have such experience but here is a link with article.
I don't know :(
Also I recommend to check AntiXSS tool, it can show you some potential xss holes. And one last note, never trust to user input.
Integrated security is your strongest option.
I'm not an ASP.Net expert, but in my PHP projects I encrypt the cookie and affinitize it to a specific client IP. This way sessions cannot migrate to a different client. Ultimately, if you want to be absolutely sure, cannot rely on cookies for authentication, but instead use HTTP Digest, since browsers will transparently re-authenticate every request within the realm. Unfortunately this option does not work with the built-in ASP.Net membership providers as the HTTP Digest option they offer is half-brained to say the least (only authenticate against AD).
What specific threat are you trying to mitigate by encrypting data? TDE is designed to mitigate the threat of accidental media loss (ie. someone find an old disk of your with all the data on it, or you loose a laptop with the database on it). This is also the threat mitigate by most other database encryption schemes, like column encryption or file level encryption (bit locker). Other threats, like accidental compromise of access to the database (ie. someone finds a SQL injection vector to your db) cannot be mitigated by TDE, since the database will offer the decrypted data to any authenticated user. To mitigate such threats it means the data is encrypted with keys presented by the user (ie. only the user session can decryt the data becaus eonyl that session know the key password), but that knocks out the 'Transparent' aspect of all these encryption schemes. Having the user encrypt data with it's own key password protects data from other users (other sessions), so it is stronger, but its very difficult to 'get right', and the user is always at risk at locking himself out of its own data by forgetting/loosing the key password.
Use integrated security and store connection string encrypted. Since encrypting the strings in Web.Config is trivial and well supported in ASP deployment and operation, just do it. Encrypting the string protects agains accidental compromise of the IIS/ASP host from a non-admin account. An admin account, or the account under which the ASP runs will always be able to read the encrypted connection string. Since the most likely attack vector will always be ASP compromise (ie. SQL injection and friends) the attacker will most likely be able to read the connection string even when encrypted, so there isn't that much benefit from it, but every little bit counts.

How do I change a windows password through asp?

I have a web application that uses Integrated Windows Authentication to validate users. Most of them are remote and don't have access to a workstation to update their AD password.
Rather than manually managing passwords my self, I'd like to put together a script so they can change them on their own.
How would I update their windows password through ASP?
If you are going to offer this in a website, you should consider the security implications. A self-service password changing website is generally considered a major security risk and is not common.
You mention that your users are remote. If the site will be public, how will they authenticate through Integrated Authentication? They only way I know to make this possible is through VPN. Otherwise, they will have to use Basic Authentication to enter their username and password. This is very insecure, even over SSL.
Here are some recommendations:
Secure the site using client certificates. If this is not possible use SSL at a minimum.
I would strongly recommend that you implement the actual password-changing logic in a secure webservice. The ASP.NET page should call the webservice to request the change.
You should store an audit trail of password changes. DO NOT store the passwords, just an event log of the user, time, and IP address.
Test very thoroughly to ensure that the integrated security is recognizing your users properly. Make sure that users cannot accidentally change other users' passwords.
There is a function in the System.DirectoryServices namespace that seems to be able to handle this. You will need to add a reference to it in order to use it.
Here is the article on how to change user passwords:
http://msdn.microsoft.com/en-us/library/ms817839.aspx
http://support.microsoft.com/kb/555071
If you can set up IISADMPWD like this, you should be able to change passwords. This is actually an ASP application which relies on a COM component.
Note that IISADMPWD is obsolete and does not ship with IIS 7.0.

How secure is basic forms authentication in asp.net?

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.

Resources