Should I rely on User.Identity value? - asp.net

I am interested in security connected with ASP.NET applications. When I am developing my websites I extensively use User.Identity.Name value to identify user. I am wondering if there is a possibility to modify request so that client could change this value and become other user. If so how to identify users then and how to distinguish superuser safely?

Yes, you can rely on this value. The whole security of ASP.NET relies on it. It is stored in an encrypted cookie that can only be decrypted by the application. If a malicious user tries to substitute the value of this cookie with another username he will not be able to encrypt the cookie because he doesn't have the machine keys.

Related

How to protect GET methods for .net application if the cookie is stolen

How to protect GET methods if the cookie is stolen since Antiforgery Token only protects the POST methods? The web application can return sensitive information via GET method.
I am using .AspNetCore claim based identity. I was trying to use Postman to view the content of the GET method, but I cannot get the it to work.
I assume this is theoretically possible. An authorized user cookie can be hijacked by a man sit in middle right?
The site is secured by SSL and I think the .AspNetCore claim based identity is session based cookie. What are the chances to break in to execute the GET methods and get returns values. How to secure the application?
It should never get to that point
Don't use just a cookie to validate a user. You should use several cookies based on each session, such as the device name or id, the device's IP address, a session ID stored in their browser, potentially something stored in their local data (permanently stored even if cookies are deleted) that validates that particular PC etc. There are plenty of other methods of security a user's identity.
However, if you use a session cookie and nothing else to authenticate a user, then you should probably revise how your application secures its users first. Because if that session cookie is stolen, then it's a bad sign for your user.

Simple password protection on a page in ASP.NET MVC

I wish to secure individual (dynamic) pages in an ASP.NET MVC application.
I do not want to use a full blown authentication system - we are already using forms authentication for the administrators of the site. Instead, this is so that we can send out links to a page with a password for specific users.
The way I am handling this currently is when a valid password is submitted we create an encrypted cookie containing the page id (Guid) and their session id and redirect them to the page. In our "Page" controller action we then validate this cookie.
So first question, is this the best (most secure) approach (aside from using forms authentication)?
Second question, can I read the machine key used by Forms Authentication to perform the encryption, or better yet use the FormsAuthentication to encrypt the cookie (the only overload I can see is one that requires a FormsAuthenticationTicket)?
Since we always generate a new machine key before deploying it would be better if all our encryption used the same key.
[Update]
Regarding how to access the machine key I found my answer at http://rich-rogers.com/archive/asp.net-c-sharp-encrypt-hash-using-machinekey-values
[Update 2]
I realize after asking this question that since I will need to maintain a list of pages that they do have access to, I would probably be better off just storing these in the current session. I can store a list of security tokens with an expiry date. Since I already have a wrapper around session, this should be easy to unit test too.
To make really secure your cookie-key, you need to make it available only on SSL pages, or else some one can get it, and even if its encrypted he can use it.
Request.Cookies[cookieName].HttpOnly = true;
Request.Cookies[cookieName].Secure = true;
Also to read: Can some hacker steal the cookie from a user and login with that name on a web site?

Store username and password ASP.NET authentication

I have a service (WCF) with which my ASP.NET page will communicate. The WCF service has hashed passwords in its data store (a file actually). The WCF service requires the username and the hashed password on every call.
Nowm the problem I'm encountering is that if I authenticate the user with forms authentication in ASP.NET, a cookie will be saved in the user's computer after the user is authenticated but I would like to save the username and hashed password too so that the user may able to use the WCF service. Where should this information should be saved so that it is safe and secure?
Should I use session variables? If I choose that option that, then should I switch from forms-based authentication and manually authenticate using session variables or use both forms-based autentication for web page access and store the username and hashed password in a session variable? What are the pros and cons of each?
Can you store the username and password (hashed of course) in another cookie? Each time you communicate, grab the cookie and send it along with the username to the WCF service.
On the WCF service end you'll have the username and the hashed username/password combo. If you apply the same hashing you should end up with the same string that you've got stored in the WCF end, if they match the user is valid.
Regards to your edit:
Not sure that there is a much of a distinction between them as you're suggestion. If you use forms authentication a session variable is created and (assuming you're using cookies) a cookie is stored that allows the session variable to be associated with the user. So even if use forms authentication you're still using session variables.
The only question really is if you want to store a hashed version of the password entered by the user in a session/cookie. The pro is that its being stored somewhere and that could potentially pose a security risk.
A completely alternative approach is rather than sending the password and re-authentication upon each request, send an authentication token that doesn't relate to the user's password. Validate this token instead.
The token could be issued upon successful login, and should use the same hashing algorithm as the WCF. Send the username and token as part of the request and validate that it is valid, authorised and still current.
Definitely not on the client side (cookies). Use the cookie to authenticate the user to ASP and for the session ID. This is the ASP.NET default. Than store the username and PW in the session.
Consider using Windows Authentication or other recommended mechanisms, since they will bring more security.
#your edit: I suggest keep using forms authentication along with related controls (or any other preimplemented method in ASP.NET). Reimplementing it on your own would make large effords for no reason - at least if you want to get the same safety as the .NET authentication brings. It really is more than comparing hashed passwords..! Also, use the session, since this is the natural place to store any additional user related data. Again - sessions are easily configured and relatively safe.

MVC 2 AntiForgeryToken - Why symmetric encryption + IPrinciple?

We recently updated our solution to MVC 2, and this has updated the way that the AntiForgeryToken works. Unfortunately this does not fit with our AJAX framework any more.
The problem is that MVC 2 now uses symmetric encryption to encode some properties about the user, including the user's Name property (from IPrincipal). We are able to securely register a new user using AJAX, after which subsequent AJAX calls will be invalid as the anti forgery token will change when the user has been granted a new principal. There are also other cases when this may happen, such as a user updating their name etc.
My main question is why does MVC 2 even bother using symmetric encryption? And then why does it care about the user name property on the principal?
If my understanding is correct then any random shared secret will do. The basic principle is that the user will be sent a cookie with some specific data (HttpOnly!). This cookie is then required to match a form variable sent back with each request that may have side effects (POST's usually). Since this is only meant to protect from cross site attacks it is easy to craft up a response that would easily pass the test, but only if you had full access to the cookie. Since a cross site attacker is not going to have access to your user cookies you are protected.
By using symmetric encryption, what is the advantage in checking the contents of the cookie? That is, if I already have sent an HttpOnly cookie the attacker cannot override it (unless a browser has a major security issue), so why do I then need to check it again?
After having a think about it it appears to be one of those 'added layer of security' cases - but if your first line of defence has fallen (HttpOnly) then the attacker is going to get past the second layer anyway as they have full access to the users cookie collection, and could just impersonate them directly, instead of using an indirect XSS/CSRF attack.
Of course I could be missing a major issue, but I haven't found it yet. If there are some obvious or subtle issues at play here then I would like to be aware of them.
It was added to offer greater protection in the case where you have one subdomain trying to attack another - bad.example.com trying to attack good.example.com. Adding the username makes it more difficult for bad.example.com to contact good.example.com behind the scenes and try to get it to generate a token on your behalf.
Going forward, it's possible that the cookie will be removed as it's not strictly necessary for the proper functioning of the system. (For example, if you're using Forms Authentication, that cookie could serve as the anti-XSRF cookie instead of requiring the system to generate a second cookie.) The cookie might only be issued in the case of anonymous users, for example.
Besides the "evil subdomain"-scenario outlined by Levi, consider an attacker that has an account on the targeted site. If the CSRF-token does not encode user-specific information, the server can not verify that the token has been generated exclusively for the logged-in user. The attacker could then use one of his own legitimately acquired CSRF-tokens when building a forged request.
That being said, anonymous tokens are during certain circumstances accepted by ASP.NET MVC. See Why does ValidateAntiForgeryTokenAttribute allow anonymous tokens?

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