Is TempData in ASP.NET MVC secure? - asp.net-mvc

I want to know about security of tempdata in ASP.NET MVC in the following scenario.
If one user is logged in and there is data passed to tempdata and it is we are keeping for next request or we are not reading it so it keeps value in tempdata. If another user logged in, then will that tempdata value also be available to the second user?

TempData uses by default Session*. Therefore it is as safe as a session can be.
A session is individual for every user, so yes.
Session Hijacking is one problem for a session, but since TempData is only valid for one request, I do not see any problems.
* Note it is possible to create a own ITempDataProvider (Credits to NightOwl888). In this case, you need to evaluate, if your provider is secure.

Related

Where does TempData get stored?

Where does TempData get stored in the ASP.NET MVC Framework (more specifically, ASP.NET MVC 2)? Is it stored at server-side, or is sent to the client?
By default TempData uses the ASP.NET Session as storage. So it is stored on the server (InProc is the default). But you could define other ASP.NET Session state modes: StateServer and SqlServer. You could also write a custom TempData provider and handle the storage yourself if you don't want to use the ASP.NET Session.
It is stored in session storage, but there is one crucial difference between TempData and Session:
TempData is available only for a user’s session, so it persists only till we have read it and gets cleared at the end of an HTTP Request.
A scenario that fits the usage of TempData, is when data needs to persist between two requests – a redirect scenario. Another scenario I can think of is to return an error message after a POST operation fails.

How can I store user data after login without having to query the database to show this data?

I need to store the user ID, his company ID and name, in a way I won't have to query the database on every postback.
I know I have options like: ViewData, TempData or auth cookie, but, are there any better solution?
Best regards,
Juliano Nunes
This sounds like a classic use of Session.
ASP.NET session state enables you to store and retrieve values for a user as the user navigates ASP.NET pages in a Web application. HTTP is a stateless protocol. This means that a Web server treats each HTTP request for a page as an independent request. The server retains no knowledge of variable values that were used during previous requests. ASP.NET session state identifies requests from the same browser during a limited time window as a session, and provides a way to persist variable values for the duration of that session. By default, ASP.NET session state is enabled for all ASP.NET applications.
ASP.NET Profile Providers mechanism looks like a thing you're looking for - especially if you're already using Membership/Role providers.
More generic article on Profile properties: MSDN

ASP.NET MVC: A PreAuthorize-like event, Good throttle point for concurrent logons?

I want to allow a new login to 'kick' a prior login session by the same account, in ASP.NET MVC.
It seems pretty clear that I'll give each browser a cooking representing the session ID. I'll track the currently active session ID in a server-side cache. If an already-active user attempts to log in, I'll verify the business logic (username, password, has been at least 15 minutes since last activity), and then update the active session ID cached at the server.
Now my issue is, a browser is holding an invalid session ID. What is the best point for me to inject a rejection or redirect to sign-in for this scenario?
I could modify the AuthorizeAttribute, but it seems like there should be a cleaner place to do this that won't require me to search and replace all my Authorize attributes, for example via a Global.asax event, or a controller event (I've already extended Controller in my project).
For example, if PreAuthorize existed, I would write some code there to test the request's cookies for a valid user/session ID pair, and if it didn't exist, I could simply remove the authentication cookie from the request, which would result in a standard unauthorized redirection.
So after a bit of research, it seems that a custom AuthorizeAttribute would typically be the correct approach. However, in my case, since I already had a custom role provider implemented, it was just a line of code to do it there. This also benefited me because I only wanted session concurrency for a single role. A side effect is that any use of web.config to control access to static files by role is also in-effect for session concurrency.

Session vs Cookie vs Custom IPrincipal

I'm working on a project where certain logged in users have a dedicated page which they can choose the url of. When a user logins in i would like to display a link "View my page". I was just wondering what is the best way to store this baring in mind it needs to be accessible for as long as the user is logged in (The site has a remember me feature as well). Would a session variable surfice? or a cookie? Or a custom IPrincipal?
Many thanks
Matt
UPDATE:
What do you guys thing of using the UserData string you can store with the authentication cookie? It seems to satisfy my requirements, but i can't say I know a lot about it.
Forms authentication (based on cookie) should be enough. Here you can read about using FormsAuthentication with custom IPrincipal:
ASP.NET 2.0 Forms authentication - Keeping it customized yet simple
This page is about how forms authentication works:
Explained: Forms Authentication in ASP.NET 2.0
When you use forms authentication, you have Authorize attribute to limit access to controllers and action. It works pretty well. Your own IPrincipal is not necessary. I wouldn't use Session, because it can be easily lost.
Thanks guys, however I have ended up using the UserData string that you can store along with the authentication cookie. This way I know the data will always be available while the user is authenticated. And since I only need to remember simple data (the users url), this seems like a good solution.
Anybody with the same problem can find more info here:
http://www.asp.net/learn/security/tutorial-03-cs.aspx (See step 4)
If what you mean is that you want to display a different custom URL for each user and you simply want to cache that URL then there's a few things to consider:
If you use a session value or a cookie then you need code for the possibility of the value not being present. Both the server session or the browser session could expire and the user could still be logged in.
If you use a cookie you could consider setting the cookie expiry to the same as the authentication cookie expiry but this still doesn't guarantee availability.
A cookie value will not be secure, it could be modified. A session value will be secure.
If you're using custom forms authentication then you could store the URL in the authentication cookie itself and then load it into a custom IPrincipal. I would advise against that as I don't feel it's the right place.
If you're just trying to cache the URL then as long as your code re-fetches the data when the value is not present then a session value or a cookie will be fine depending on the level of security required.
If I have read that wrong and you just want to show/hide a link to depending on whether a user is authorized or not you can simple use
<% if (User.Identity.IsAuthenticated) { %>
view my page
<% } %>
And have your MyPage action in your controller render the dedicated page for the user.

Why would ASP.NET MVC use session state?

Recommended by the ASP.NET team to use cache instead of session, we stopped using session from working with the WebForm model the last few years. So we normally have the session turned off in the web.config
<sessionState mode="Off" />
But, now when I'm testing out a ASP.NET MVC application with this setting it throws an error in class SessionStateTempDataProvider inside the mvc framework, it asked me to turn on session state, I did and it worked. Looking at the source it uses session:
// line 20 in SessionStateTempDataProvider.cs
Dictionary<string, object> tempDataDictionary =
httpContext.Session[TempDataSessionStateKey] as Dictionary<string, object>;
So, why would they use session here? What am I missing?
========================================================
Edit Sorry didn't mean for this post to debate on session vs. cache, but rather in the context of the ASP.NET MVC, I was just wondering why session is used here. In this blog post also Scott Watermasysk mentioned that turning off session is a good practice, so I'm just wondering why I have to turn it on to use MVC from here on.
Session is used for the TempData store. TempData is a highly limited form of session state which will last only until the next request from a certain user. (Edit In MVC 2+, it lasts until it is next read.) The purpose of TempData is to store data, then do a redirect, and have the stored data be available to the action to which you just redirected.
Using Session for the TempData store means that any distributed caching system which already handles Session will work for TempData. Avoiding using Session directly when TempData will do has a couple of advantages. One is that you don't have to clean up the Session yourself; TempData will "expire" on its own.
Recommended by the ASP.NET team to use
cache instead of session
#ray247, could you provide a reference for this? Session and Cache are different by nature and should be used depending on application requirements. For example storing user specific data into the cache could lead to undesired behavior. Of course if you really want to avoid using session you could provide your own implementation of the ITempDataProvider interface.
Hmm... May be you've read about persisting of the heavy objects or relatively rarely accessed objects - it's definitely better to put them into cache, but for light objects or for data that is required at every request there is no better technique than put them into Session.
Sessions are not evil if you are using them correctly.
Just an additional thought. TempData has its own purpose and MS knew there will be different school of thoughts with respect to TempData persistent mechanism. So, by default they made the persistent store to be SessionState. But the design is still very flexible. Based on the needs of the project and the governance that guides it you can create your own tempdata provider to suit specific requirements.
Here are some pointers to the resources
TempData
Here are some additional improvements in TempData implementation
TempData Improvements
Here's an alternative implementation using MS Velocity Distributed Caching.
Velocity TempData Provider

Resources