Cookie Persistence : cannot set expiry date - asp.net

I am attempting to change an MVC web site that was storing some info in Session to store it in a cookie but am having some issues with the expiry of the cookie.
Scenario
While logging in to the site a cookie is created and added to the current HttpContext Response cookies collection. The code piece used to write the cookie is as follows :
HttpCookie userCredsCookie = _context.Response.Cookies.Get(Constants.Web.UserCredentialsCookieName) ?? new HttpCookie(Constants.Web.UserCredentialsCookieName);
userCredsCookie.HttpOnly = true;
userCredsCookie.Secure = true;
userCredsCookie.Value = user.ID.ToString();
userCredsCookie.Expires = DateTime.Now.AddMinutes(user.CompanySessionTimeout + user.TimezoneOffset);
_context.Response.Cookies.Add(userCredsCookie);
I have experimented with removal of the line that sets the expiry of the cookie and have found that the cookie is generated and stored at the client as expected.
When i inspect the response from the server using Fiddler i can see that the userCreds cookie is being returned :
Response sent 111 bytes of Cookie data:
Set-Cookie: UserCreds=e2ce8200-fb38-45b9-8aec-4d93e6640a84; expires=Mon, 09-Oct-2017 16:20:43 GMT; path=/; secure; HttpOnly
when the expiry is not set the response has :
Response sent 72 bytes of Cookie data:
Set-Cookie: UserCreds=e2ce8200-fb38-45b9-8aec-4d93e6640a84; path=/; secure; HttpOnly
As long as the expiry is not set, the cookie is accepted by the browser and sent on the subsequent requests made from the browser.
It feels like the problem is due to the format of the date in the response but i cannot find anything to allow me to change that format.
Any help would be greatly appreciated.
Regards
Monty
Update - Possible cause located
I have found that the problem i am having is to do with timing. It seems that my dev pc may be processing the responses from the ajax call that is setting the cookie too fast (??? is that even possible ???).
While i was debugging the front end code to ensure things look fine from that perspective i found that by placing a break point just before the line which was setting the window.location to a url that is in the result of the ajax call, the subsequent call was made with the cookie being on the request.
Perhaps, by causing the processing of the callback to pause, gave the system time to persist the cookie. I assume the process of persisting a cookie is to do a validation check then store the data. That would mean that it takes a little longer to validate the cookie when their is an expiry date set. Perhaps the reason why a cookie with no expiry set was persisting but ones with an expiry were not was cause the load of a new url interrupted the process, thus causing the cookie to not get stored.
By adding a 1 millisecond delay (yep, just 1 millisecond) in the success handler of the ajax call i was able to successfully have the cookie persisted to the browser and included in the call made to load a return url that is in the ajax response.
Does this sound even possible?

try with this code
int result = Convert.ToInt32(user.CompanySessionTimeout.ToString()) + Convert.ToInt32(user.TimezoneOffset)
and then pass
userCredsCookie.Expires = DateTime.Now.AddMinutes(result);

Related

Conditionally updating cookie expiry time in nginx to find the idle time

I'm trying to implement a solution to identify if there was an idle time of X minutes between two requests.
For this, I'm planning to use the following approach.
Initially, set a cookie from the application side. The expiry time of this cookie is set to X minutes.
Whenever there is a request, in nginx, I will check if the cookie expiry time is passed or the cookie is available.
If the cookie is available, and not expired, I will update the expiry time again with X minutes. Otherwise, delete the cookie.
On the server-side, I can check the availability of the cookie and if available, I can conclude the previous request was within X minutes.
To implement this solution, I will need some code snippets as below.
if cookie-exists and cookie.expirytime > currentTime
Set-Cookie: MY_COOKIE=SOMEVAL; Max-Age=X*60; Secure; HttpOnly
else
Drop-Cookie MY_COOKIE
endif
How can I implement this condition check and cookie modification in nginx? Is it possible to do without lua?
I don't want to implement this logic on the application side because - there are multiple applications served through nginx and I want to keep the logic common to all. If the user is hitting any of the applications, the cookie should be updated.
Browsers do not send expired cookies, so Nginx will never receive it. You could potentially set 2 cookies: one that expires, and another that identifies repeat visitors.

The behaviour of HttpOnly cookie on aspx

I did an HttpOnly cookie using the article:
https://learn.microsoft.com/pt-br/dotnet/api/system.web.httpcookie.httponly?view=netframework-4.7.2
the creation of HttpOnly cookie is the following:
// Create an HttpOnly cookie.
HttpCookie myHttpOnlyCookie = new HttpCookie("LastVisit", DateTime.Now.ToString());
// Setting the HttpOnly value to true, makes
// this cookie accessible only to ASP.NET.
myHttpOnlyCookie.HttpOnly = true;
myHttpOnlyCookie.Secure = true;
myHttpOnlyCookie.Name = "MyHttpOnlyCookie";
Response.AppendCookie(myHttpOnlyCookie);
// Show the name of the HttpOnly cookie.
Response.Write(myHttpOnlyCookie.Name);
Ok, I saw this article that says:
https://latesthackingnews.com/2017/07/03/what-is-httponly-cookie/
HttpOnly tells the browser to save the cookie without displaying it
to client-side scripts. A secure flag, on the other hand, forces the
browser to send cookies through an encrypted channel such as HTTPS,
which stops eavesdropping, especially when an HTTPS connection is
downgraded to HTTP through tools such as SSLStrip and so on.
Ok,
but I did an http-only cookie in my .aspx webpage but I could see it through Chrome's cookies file:
C:\Users\<user>\AppData\Local\Google\Chrome\User Data\Default\Cookie
I set the flags:
myHttpOnlyCookie.HttpOnly = true;
myHttpOnlyCookie.Secure = true;
Question 1- if HttpOnly tells the browser to save the cookie without displaying it to client-side scripts, why could I access the name of the cookie within Chrome's cookie file?
Question 1.1- Is its content accessible, but just not using scripts?
Question 2- It's silly, but I can't access the HttpOnly cookie via aspx using the code:
HttpContext.Current.Request.Cookies["test_MyHttpOnlyCookietest"]
Is it the only way to access it via server side?
Question 3- When I put myHttpOnlyCookie.Secure = true;
I can't acess it via a non HTTPS connection - is that right? Just using https I can access it?
Question 4- If I use myHttpOnlyCookie.Secure = true, there is an encryption and decryption.
How costly is this in processing power?
Http Only cookies are not exposed to client scripts, of course the browser has access to it since it supposed to send it back to the server.
You can access it using Request object in Asp.net like any other cookie.
Setting "Secure" attribute means that the cookie can be used only in a secure connection i.e. https, so it won't work under http. The overhead of encryption/decryption is not specific to cookie, actually it happens in TCP level for all data transfers, and the overhead is like any other https connection (which are not that much considering today's servers). The size or number of cookies can affect the overhead because the data is being transferred in any call.

Are my cookies really HTTP only? Flag is absent in Cookie request header

Ive made some configurations to (finally) have my cookies set on HTTP only.
"Seem" to work.
Ive tried them with postman and I have the following:
When I hit the login page:
On the cookies section, my cookie with name JSESSIONID appears to be HTTP only (it has the check)
When I enter to the logged area , the same result...
The headers dont give me more details.
Then,
I check it with google chrome. I open the developers toolbar.
I load the login page.
At the headers on the response headers I get
Set-Cookie: JSESSIONID=434434..... HttpOnly
So, its fine (I guess).
Then I reload the page (or sign in).
Then the problem:
No response headers received.
The Request Headers brings my cookie (with the same ID at then the previous one) without the httponly, host info or any other cookie value I set before.
At the cookies tab I get Request Cookies only and no Response cookie.
And the request cookie is non http-only
At my resources tab, the Cookie is there, as HTTP only and with the previous values I set.
My question now is... Is it a really http-only cookie? Or my configuration is not properly set?
Should I always get the response cookie or the request cookie should be always http-only (In case I am trying to set it as http-only) or is this behavior normal (or at least accepted) ?
When I try to print my cookie with Javascript at both scenarios I get a null as response (what makes me think then it is correct).
Ideas?
Client doesn't send cookie attributes other than name and value back to server.
See also RFC6265 section 4.2.2 (emphasis mine).
4.2.2. Semantics
Each cookie-pair represents a cookie stored by the user agent. The
cookie-pair contains the cookie-name and cookie-value the user agent
received in the Set-Cookie header.
Notice that the cookie attributes are not returned. In particular,
the server cannot determine from the Cookie header alone when a
cookie will expire, for which hosts the cookie is valid, for which
paths the cookie is valid, or whether the cookie was set with the
Secure or HttpOnly attributes.
Everything's behaving as specified.

cookies - the misunderstanding

My goal is that I want to log into a site with some java code and do some work when logged in. (in order to write some java cooking handling I first need to understand how this all actually works)
The problem is that I can't quite figure out how to manage the cookie session.
Here's what I've observed when using chrome's dev. tools:
1) on first request for the site's url I send no cookies and I get some in response:
Set-Cookie:PHPSESSID=la2ek8vq9bbu0rjngl2o67aop6; path=/; domain=.mtel.bg; HttpOnly
Set-Cookie:PHPSESSID=d32cj0v5j4mj4nt43jbhb9hbc5; path=/; domain=.mtel.bg; HttpOnly
2) on moving on log page I now send (on HTTP GET):
Cookie:PHPSESSID=d32cj0v5j4mj4nt43jbhb9hbc5;
__utma=209782857.1075318979.1349352741.1349352741.1349352741.1;
__utmb=209782857.1.10.1349352741;
__utmc=209782857;
__utmz=209782857.1349352741.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);
__atuvc=1%7C40
and indeed when I check my stored cookies (after my first get request for the site's main url) in chrome's cookie tab - they exist in the way they're passed on the next get/post request.
Can you explain what's really happening after my 1st cookies are received and why such name/value pairs are stored?
There's a Javascript from Google Analytics on the page which sets some cookies.

Multiple Set-cookie headers in HTTP

I'm writing a small class that acts as a very basic HTTP client. As part of a project I'm working on, I'm making it cookie aware. However, it's unclear to me what happens when my client receives multiple "Set-Cookie" headers with the same key but different values are set.
For example,
Set-Cookie: PHPSESSID=abc; path=/
Set-Cookie: PHPSESSID=def; path=/
Set-Cookie: PHPSESSID=ghi; path=/
Which one of these is supposed to be the value for PHPSESSID? This usually ends up happening when you call session_start() and then session_regenerate_id() on the same page. Each will set its own header. All browsers seem to do okay with this, but I can't seem to get my client to pick the right one out.
Any ideas?!
RFC 6265 section 4.1.2 states:
If the user agent receives a new cookie with the same cookie-name,
domain-value, and path-value as a cookie that it has already stored,
the existing cookie is evicted and replaced with the new cookie.
Notice that servers can delete cookies by sending the user agent a
new cookie with an Expires attribute with a value in the past.
So I would process the headers in order given and overwrite them if there is a duplicate. So in your case you would have just one PHPSESSID=ghi.
RFC 6265 states:
Servers SHOULD NOT include more than one Set-Cookie header field in the same response with the same cookie-name.
I would therefore be very concerned if your service sends multiple Set-Cookie headers with the same key. Especially because I have seen user agents and proxies behave unexpectedly - sometimes taking the value of the first header, sometimes rearranging headers.
As a client, the typical user agent behavior seems to be to take the value of the last header. The RFC alludes to that behavior with this statement:
If the user agent receives a new cookie with the same cookie-name, domain-value, and path-value as a cookie that it has already stored, the existing cookie is evicted and replaced with the new cookie.

Resources