Consider a hypothetical bank application, where we have accounts and some group of admins. Each admin has modification rights on some of accounts. To save modifications done for an account, application sends account id on edit page. A admin can change post request by using tools like fiddler. If he/she changes account id to some account id on which he/she is not authorized. Then what is the best way to detect it.
What strategy should I use to re-validate every piece of data for authorization on post-back? My concern is more towards design, not code.
In other words, how real world applications make sure that even if user is changing postback request from any tool, application is able to detect it.
Should I re-validate every piece of data for authorization on post-back?
Yes, that is correct. You should start with a 'All input is evil' philosophy and then prove that statement incorrect by validating each data point. If your entire data doesn't pass your validation, then your input is indeed evil.
Smart web applications employ both client-side and server-side validation. Client-side validation to quickly alert user on whats wrong/missing without making a server round trip and server-side validation to make sure that wrong data doesn't fall through the cracks even if someone 'fiddles' with the client side validation code (and overrides it).
Unfortunately, encrypting the data on client side won't work as then you have the keys on the client side (in JS code) as well. That won't prevent a malicious user to encrypt a malicious payload. Also obfuscations like hidden field etc. are inefficient for a malicious attacker. FYI, you don't even require fiddler to change fields/post params etc. - all you require is a firebug extension.
The mantra is "Validate every thing on server side". Period.
For Critical Applications Like Banking, i will suggest follwing security steps
1) Send Encrypted Account ID
2) Keep that account id in a hidden field and when user post data take account id from hidden field not form the textbox or label.
3) re-validate every piece of data for authorization on post-back.
Related
I am creating a new asp.net MVC 5 application. Authentication is handled by a third party using smart cards. Once a user is authenticated by the third party, I am sent the user's unique ID (inside the http header) which I match up against my database in order to find relevant information about said user (roles, display name, etc.).
Currently, on every page request, the sent user ID is compared against the database, and checks are performed to ensure the user has the proper permissions to view the requested page. While this works, it sure seems like a bunch of needless database hits when all the user information could just be stored in a cookie.
If I was using Individual User Accounts for authentication, what I am looking to do would simply be built in using Identity and OWIN. But since I am not handling the authentication, but merely the authorization, is there a way to use all the nice features of Identity and OWIN (claims and cookies specifically)? If not, how might one go about this?
Also, of particular interest to me is when a role is added or removed. Using OWIN with Individual User Accounts, updating the cookie is as simple as logging the user out, and then back in immediately in the background. That functionality would also be desired for any solution presented.
Any insight would be extremely helpful. Thanks for reading!
You could do what you're asking by directly storing values in a custom cookie, but for your purposes it sounds to me like you might be more interested in utilizing sessions to track that info. This will keep all of your actual data stored server-side, which is more secure as it isn't vulnerable to cookie modification and it allows you more freedom to control the state (for your role example, you wouldn't have to "update" the cookie at all, just update the session variable on the server side to add or remove the role as needed).
Figured it out. Found a great article that really helped:
http://www.khalidabuhakmeh.com/asp-net-mvc-5-authentication-breakdown-part-deux
When a customer signs up for a site, we want to let them know whether a username/email is available for use.
We have a httphandler that serves the purpose of feeding a jquery script that showsthe customer whether or not their desired username/email is available.
The question is:
The service can clearly be seen being called when you view the request in fiddler.
It shows /emlhandler.asmx?name=xxxxxxxxxxx#yyy.com
From the handler, a simple 0 or 1 is returned to indicate whether or not the name/address is available.
My concern is that this seems like a major security issue that would be very easy for an inexperienced person to exploit to discover all the users on the site.
So friends, how do you protect your site info and still allow the ajax callback to provide a great user experience?
Thanks.
Heath
You are being slightly paranoid here. Every site that allows user registration has to do something similar. One thing you can reasonably do is add a slight delay (maybe 2 or 3 seconds) to the handler's processing in order to reduce the likelihood or ease of a brute-force attack. Frankly, I don't think anyone would bother.
Another option is just to ignore repeated emails and send a verification email before a user's registration actually becomes active. If a new user attempts to use an existing email, the original email owner receives the verification and can cancel or ignore it. But I don't recommend this.
I'd say the vast majority of the sites I've used will just immediately say "this email address is already registered... did you forget your password?" Just knowing an email address is already in use on a given site does not in itself represent a security breach.
One possible solution would be to only enable POST requests for that method.
And since you cannot invoke services from JavaScript from another domain (XSS - Cross-site Scripting) without your authorization, then you would be protected.
However this technique would prevent malicious users from calling your web service to discover user names but this wouldn't prevent the user to automate a process to simulate user entering data in a text box to force a call to the service, in that case, perhaps you could allow just a number of requests per user in an X amount of time.
You could keep track of the number of attempts using the Session object from your web service
Another approac would be to add a re Captcha to your site, however this would decrease the level of responsiveness if you used to allow your users to capture a user name and as soon as they write you call your service. Implementing would require your users to write the auto-generated captcha in order to submit your data
I am trying to figure out how to store some user information which will control content visibility in a way that will:
Not require constant trips to the server to query SQL to see what the user does/does not have access to AND
The user cannot edit in the browser's developer tools/console
Cookies, Query Strings and even HTML5 Local Storage or SQLite are all great storage options, but they can all be edited by a tech savvy user. How do I control content based on a user's security level while limiting queries and preventing users the ability to hack around it?
The only way to prevent the user from seeing specific content is to validate their access to the content server-side and not render it to them. Any client-side validation can be circumvented. Even if you devise a way to locally store information that the user can't see, you'd still be sending the content to them and using client-side code to check that value.
The user can see any content you send them.
You don't necessarily need to make constant trips to the SQL database to check roles and permissions. You can persist some cached roles and authorizations server-side, such as in the session state, and validate against those for the life of the user's session. At that point you're not incurring a performance cost because the user is requesting pages anyway. With each page request, you would simply determine what the user can or can't see in the response.
For an online examination system, user actions/answers to be stored and later retrieved if user connection is down.
Which logic should be preferred, client side logic [cookie], or server side logic [Session/Database]?
[Edit]
How user answers will be stored? using specific timer interval for storing user answers? or after specific parts of exam? What is best practice for implementing such solutions?
If you want the answers to be available even when the user connection is down, you need to store them on the client side. If they end up being more than you can fit in a cookie, try a library like PersistJS.
As long as you are timing the exam on serverside you can use a cookie to store the data required to remember the options checked. But if the client does not respond even after the duration of the examination is over we would need to invalidate the cookies.
I am assuming you submit the data at the end of the exam here.
Cookies are generally used to store user information in most sites with an application form to enhance user experience.
Here's a link on implementing Javascript cookies
I have 2 applications, each in different domains. When a user comes to the first application, clicks a link, the user is sent to the second application.
My problem is as follows: I need to persist a sessionId from the first application to the second application. Simple enough but here's the catch. I can't use query string and I can't use cookies(since in different domains). I was thinking, is there a way to insert custom values into HTTP Headers or set some form values on an intermediate page which would then POST to the second application? So the process would be as follows:
User clicks a link on the first page, this takes the user to an "intermediate" page, this "intermediate" page sets a sessionId value in the form or http Header, then the "intermediate" page sends the user to the second application via a POST where the app will have the sessionId.
I can't use a Server.Transfer since the app is not on the same server. Help?
This is how Microfot tried to do it Does Issuing Passports Make Microsoft a Country?.
You could try and make a secure SOAP or XML request with a secure token referencing a session id you stored for the user in a shared database. You could then load the user's session based on that session id stored in the db if a match is found.
One way that you could do it is to use webservices. Before the user is to switch sites, you could give the user an unique authentication token that has been agreed upon prior to leaving.
Another thing you could do (this is not a great solution, but it works) is to use frames, and to send the child frame information through javascript (login information). I really don't like this method, because it presents so many problems that its best avoided.
What I mean:
Web services: Communicate with the other site to say "this user is currently logged in here," you can do this at login (depends how much you trust the other domain), or you can do it when the user requests to leave
Giving the user an authentication token: You can post it as a form element. Or if you had an agreement with both domains you could send it to a URL that could later be interpreted as a rediection service+authentication token confirmation portion. I.E.: domain.com/page/token+pageid-mixture
Use OpenID. It's designed for this purpose (common authentication to web sites on multiple domains). The protocol's been under development for years and has probably encountered and solved a lot of the problems you'd be likely to run into if you roll your own solution.