I see you can set the expiration using CookieOptions when appending a new cookie to the response. However, HttpContext.Request.Cookies returns an IRequestCookieCollection, which only seems to give you key/value pairs.
Is there a way to read the CookieOptions (specifically the Expiration) for request cookies?
I'm using .Net Core (1.0.0-preview2-003131)
NOTE: I need to read the expiration of an arbitrary cookie in request processing, not the expiration of the framework generated auth cookie.
I'm getting that by reacting to the event "OnValidatePrincipal"
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
...
Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = CookieAuthenticationEventHandler.ValidatePrincipalAsync
}
});
And then I can access, once the principal is validated, when the cookie will expire in my ValidatePrincipalAsync with the property context.Properties.ExpiresUtc
To be able to get that expires property later in my controller, I'm adding it in my HttpContext this way:
context.Request.HttpContext.Items.Add("ExpiresUTC", context.Properties.ExpiresUtc);
But I'm not really happy with that part, maybe someone can give you a better way to access it directly in the controller without having to get it from the OnValidatePrincipal.
No, HTTP does not include any details about cookies sent on requests, only their name and value. The auth cookie workaround only works because the expiration is also embedded in the value.
Related
I am attempting a performance test using JMeter.
The first controller performs a POST request to create a token en assign it to a variable.
The folloowing requests use this cookie to authenticate.
What I noticed is that after the first request with the cookies, the response contain a Set-Cookie header for each of the cookies.
Following requests use the old cookies (from the cookie manager) and the new cookies for the response.
I would like to overwrite the original cookie with the value of the new cookie.
I moved around the Cookie manager and edited the settings, but to no avail.
In my application I have filter that sets cookie:
HttpContext.Response.Cookies.Append("myCookie", "value")
When I print cookie value in my view:
HttpContext.Request.Cookies["myCookie"];
it is not there. If I refresh page cookie is set. This happens because using Response.Cookies.Append does not update Request.Cookies collection. Is there way to view current cookies with changes made during request?
In my web application I have IAsyncActionFilter, that updates cookie, however corrected value is visible only after page is refreshed, and I would like to finish current request with new value. I know that it will be set by browser when response finishes, but I already know that I have new value for that cookie, and I would like to propagate this value to views reading cookies.
No. This is how cookies work. They are sourced from the client. In other words, the cookie is set by the client after it receives the response from the server with the Set-Cookie header. It's then only after the client makes another request, sending the cookie back, that it exists server-side. It's not clear what you're trying to achieve ultimately here, but you need to force a new request after setting a cookie, to access that cookie, even if that's simply returning a redirect to the same page.
I have the django view to set the value in cookies 'no_show_dialog' when a user clicks 'Don't remind me anymore' in the modal dialog.
Now i changed that dialog completely and want to reset that cookie for all users, so they will have to see it again at least once.
I know there is a way to delete the cookie in a view for a particular user:
response.delete_cookie('no_show_dialog')
But how to loop over all users and remove that cookie once?
You can't do that. Cookies are stored on the client; the only time you have access to them is when the particular browser makes a request and receives the response.
The best thing to do here is to simply use a different name for the cookie from now on. This will ensure that no users will have it set initially. Alternatively you might consider using the session for future settings.
As Daniel said you cannot delete all cookies in response as they are stored on client side.
In Django you create a response object for a particular request object in your views. Which means that you can only delete a cookie for that particular request and not for all the requests that was served by your Django server.
What you can do here is set expiry time for a cookie by using max_age as keyword argument in set_cookie method For Example :
response = HttpResponse('your response')
response.set_cookie('user_id', user_id, max_age=30)
return response
This will expire the cookie after the specified time for every client.
We’re working on an OWIN MVC5 project. We use an own implementation of IUserStore<T> to integrate the user-management which is part of our companies framework. So far this works fine.
We want to provide role membership and other security configuration through claims. I have seen (and quickly tested) the ways of either implementing IUserClaimStore<T> or of attaching a ClaimsIdentityFactory to the UserManager.
In both scenarios, I see the issue that the claims are stored in the user’s cookie and when a role or another claim changes behind the web app (through another application which directly accesses the storage of the user management), the users cookie contains the old claims and the user has too much or too less permissions than she ought to have.
A possibility that came into my mind is, to check at every request or at requests in some time interval, if the backend-configuration of the users claims has been changed, and if yes, to refresh the users cookie.
Is this the right approach or does MVC5/Owin spare a more elegant/efficient way to comply with this requirement. If it is the right and only approach, where would be the most efficient place to check and refresh the cookies information?
We added this feature to 2.0, here's how you would configure the CookieMiddleware to get fresh claims every 30 minutes (regenerateIdentity should call into the code that you use to generate the ClaimsIdentity for users when they sign in, and validateInterval controls how often regenerateIdentity is called, but only if the old cookie is still valid)
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider {
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
Nope, this is in essence what you would have to do if you have the requirement that the cookie be 100% up to date at all times.
The Katana cookie middleware options class has a OnValidateIdentity callback for every time the cookie is presented -- you could check in there and then re-issue the cookie. This is how the ASP.NET Identity 2.0 bits work to expire a cookie if a user's password was changed since the cookie was issued.
Another option might be to use SignalR in a design where logged in user browsers are directed to reacquire the cookie via an Ajax call.
First, I want to make sure I got the CSRF token workflow right.
The server sets a cookie on my machine, on the site's domain. The browser prevents access to this cookie from other domains. When a POST request is made, I send the CSRF token to the server that then compares it to my cookie. It they're not the same, a 403 Forbidden page is returned.
Now, if I manually change the value of the token in the cookie and send that new value in the POST request, should the server return a 403 or not? Does the server need to validate the token agains a value stored on the server or on the cookie?
I am using the default implementation of CSRF protection on Django 1.3 (https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/) and it validates the token sent in the request against the token only.
How do you send the token?
Usually, the tokens should be some function (with a secret key - known only to the server; e.g., MAC) of the cookie! not the cookie.
Than the flow is as follows:
1. Client sends the server request with a cookie.
2. Server returns a web page with CSRF token(s) for different purposes (e.g., forms or just a simple get requests via the URL).
3. The client performs some action (via POST or GET) and sends request with the token (in the request body or in the URL) and with the cookie.
4. The server is stateless, but it can verify that the request was sent by the same client by calculating the function (with the secret key that the server knows) on the cookie (or on part of it), and comparing the output with the token.
In the case of CSRF, the cookie is automatically appended to the request by the browser, but the attacker (that probably even doesn't know the cookie) cannot add the corresponding tokens.
I believe you should do something like this.
Now, if I manually change the value of the token in the cookie and
send that new value in the POST request, should the server return a
403 or not? Does the server need to validate the token agains a value
stored on the server or on the cookie?
The server should be stateless (usually). You don't want to verify the token every request against some value in a database or something like that. It is better to verify against the cookie.
In that case, if you change the token, than it probably won't match the cookie, and you should send 403.
TL;DR: Yes, either you, or the framework you are using, needs to have server-side logic to validate a CSRF token. It cannot be a cookie, it has to be something that requires the user to be on your page, versus click on a link an attacker provides.
You've got the workflow pretty much correct. The first step is to generate a cryptographically random string that cannot be predicted by an attacker. Every programming language has its own construct to do this, but a 24 - 32 character string should be good to serve the purpose.
Before we get to the next step, let's make sure we know what threat we're dealing with - we don't want an attacker to make a request on behalf of the user, so there should be something that is accessible to the browser that requires the user to perform an action to send the token, BUT, if the user clicks on something the attacker has set up, the token should not be sent.
Given this, the one way this should NOT be done is using cookies. The browser will automatically send cookies every single time a request is made to the domain the cookie is set on, so this automatically defeats our defense.
That said, let's go to the next step, which is to set this token in a way that is verifiable by you on the server side, but not accessible to the attacker. There's multiple ways to do this:
1) A CSRF Header: This is done in many node.js/Express installations - the CSRF token is sent as a header, to be specific, a X-CSRF-Token header. After generating this token, the server stores this in the session store for that particular cookie. On the front end, the token is stored as a JavaScript variable, which means only requests generated on that particular page can have the header.. Whenever a request is made, both the session cookie (in the case of node.js, connect.sid) and the X-CSRF-Token is required for all POST/PUT/DELETE requests. If the wrong token is sent, the server sends a 401 Unauthorized, and regenerates the token, requesting login from the user.
<script type="text/javascript">
window.NODE_ENV = {};
window.NODE_ENV.csrf = "q8t4gLkMFSxFupWO7vqkXXqD";
window.NODE_ENV.isDevelopment = "true";
</script>
2) A Hidden Form Value: A lot of PHP installations use this as the CSRF defense mechanism. Depending on the configuration, either a session specific or a request specific (latter is overkill unless the application needs it) token is embedded in a hidden form field. This way, it is sent every time a form is submitted. The method of verification varies - it can be via verifying it against the database, or it can be a server-specific session store.
3) Double Submit Cookies: This is a mechanism suggested by OWASP, where in addition to sending the session cookies via the header, you also include it in the forms submitted. This way, once you verify that the session is valid, you can verify that the form contains the session variables also. If you use this mechanism, it is critical to make sure that you validate the user's session before validating CSRF; otherwise, it introduces flaws.
While building/testing this mechanism, it is important to note that while a lot of implementations limit it to POST/DELETE/PUT transactions, this is because it is automatically assumed that all sensitive transactions happen through this verbs. If your application performs sensitive transactions (such as activations) using GET, then you need this mechanism for GET/HEAD also.