I've got a simple scheme for keeping a user logged in using a cookie. I want the cookie to contain two name value pairs when i am done. I've used this basic implementation before, I can't understand why it isn't working for me this time.
protected void SetAuthCookie(string EventCode, string id)
{
SHA1 sha = SHA1.Create();
byte[] data = sha.ComputeHash(Encoding.UTF8.GetBytes(id));
HttpCookie AuthCookie = new HttpCookie("MyCookie");
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
AuthCookie["eventcode"] = EventCode;
AuthCookie["id"] = sBuilder.ToString();
Response.Cookies.Add(AuthCookie);
}
Here's what i've discovered so far: If I comment out "AuthCookie["eventcode"] = EventCode;" then in my browser i see that MyCookie is left with value "id=foo".
Likewise, if I comment out "AuthCookie["id"] = sBuilder.ToString();" I see MyCookie is left with value "eventcode=foo".
What I want is MyCookie to have a value of "eventcode=foo&id=bar". If i leave neither line commented out, however, In my browswer, i see that MyCookie has no\empty value. What gives?
The only difference in previous implementations is thatI haven't processed the 'id' parameter - it was already a guid. I think the fact that it is a cryptographically hashed string is a red herring, because hard coding 'foo' as the value for cookie value for 'id' or 'eventcode' leads to the same outcome. I may be wrong about that
HttpCookie AuthCookie = new HttpCookie("MyCookie");
AuthCookie.Values["eventcode"] = EventCode;
AuthCookie.Values["id"] = sBuilder.ToString();
AuthCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);
This should work, says MSDN
I've found Google Chrome to have a few weird issues with localhost/dev websites. Could this be the case?
Related
I am using VS2015, C#.
My cookie value is:
Provider=Custom&Email=someemail#gmail.com&UserName=John&FirstName=Test&LastName=LastTest&Expires=11.7.2016
11:03:05
I am trying to get this value with:
HttpContext context = HttpContext.Current;
HttpCookie cookie = context.Request.Cookies["Login"];
string provider = cookie["Provider"];
string email = cookie["Email"];
both provider and email are null. How can I get values from cookie?
EDIT
Cookie is saved with:
HttpCookie cookie = new HttpCookie("Login");
cookie["Provider"] = "Custom";
cookie["Email"] = "test#gmail.com";
Response.Cookies.Add(cookie);
SECOND EDIT
I think the problem is encryption. I am using my own encrpytion mechanism. Cookie.value looks fine after decryption, but Cookie.Values is a little bit different than original. I think that's the problem.
Cookie.Value (before encryption): Provider=Custom&Email=test#gmail.com
Cookie.Value (after decryption): Provider=Custom&Email=test#gmail.com
Cookie.Values (before encryption) :{Provider=Custom&Email=test%40gmail.com}
Cookie.Value (after decryption - is different): {Provider%3dCustom%26Email%3dtest%40gmail.com}
Try below
HttpCookie cookie1 = Request.Cookies["Login"];
if (cookie1 != null)
{
string provider = cookie1["Provider"].ToString();
string email = cookie1["Email"].ToString();
}
I am using Fortify to scan my code. It is identifying the error "Header Manipulation: Cookies". Further it says "includes unvalidated data in an HTTP cookie". My code is below.
String cookieName = "Foo";
System.Text.RegularExpressions.Regex rgx = new System.Text.RegularExpressions.Regex("[^a-zA-Z0-9 -]");
String FullCookieName = ".OmniPro" + cookieName;
FullCookieName = rgx.Replace(FullCookieName, "");
HttpCookie oldCookie = Request.Cookies[FullCookieName] ;
if ( oldCookie != null )
{
oldCookie.Expires = DateTime.Now.AddDays( -1 );
Response.Cookies.Add( oldCookie );
}
The error is identified on "Cookies.Add".
My intention is to just expire the old cookie. I have found no way to make Fortify happy. Any help would be appreciated.
The problem is taking the old cookie and then sending it back out. Cookies are not considered a trusted input for Fortify because they can be edited by the user. You would want to validate what is inside the cookie before adding it to the response. Even when you do this, Fortify will still likely report the issue. When doing input validation Fortify doesn't trust your validation inherently. You have to create a custom rule to do that. Once you think the input is sufficiently sanitized you could also just suppress the issue.
Fortify has a user community at https://protect724.hp.com that is also monitored by support. You may get quicker answers there.
I changed the code to be like below and Fortify accepted it.
String cookieName = "Foo"
System.Text.RegularExpressions.Regex rgx = new System.Text.RegularExpressions.Regex("[^a-zA-Z0-9 -]");
String FullCookieName = ".OmniPro" + cookieName;
HttpCookie oldCookie = Request.Cookies[FullCookieName];
if (oldCookie != null)
{
String DeleteCookieName = rgx.Replace(FullCookieName, "");
HttpCookie expiredCookie = new HttpCookie(DeleteCookieName) { Expires = DateTime.Now.AddDays(-1) };
HttpContext.Current.Response.Cookies.Add(expiredCookie); // overwrite it
}
Thanks
It seems to me that the extension .OmniPro has a very specific use case, which I don't question. However, the regular expression doesn't seem to be essential.
Much simpler code passes the HP's Fortify scan for header manipulation prevention:
HttpCookie expiredCookie = new HttpCookie(DeleteCookieName)
{ Expires = DateTime.Now.AddDays(-1) };
HttpContext.Current.Response.Cookies.Add(expiredCookie); // Overwrite cookie.
Moreover, for these kind of cookies which expire immediately (see DateTime.Now.AddDays(-1)) I'm a bit sceptical if it's not a false positive, because this cookie can be never fetched - it simply expires before it has been created.
I have an application that leverages a cookie to support a quasi-wizard (i.e. it's a set of pages that are navigated to by each other, and they must occur in a specific order, for registration).
When the Logon.aspx page is loaded - the default page - the browsers cookies look right.
There's one cookie and it has the right value. This ensures that the next page, which is an enrollment agreement, knows that it was loaded from the Logon.aspx page. However, when I get to that page the browsers cookies look much different:
Now we have two of the same cookie.
This doesn't appear to be causing any real issues - but I can't be sure it won't. So, let me show you the code I'm using to set the cookie (because maybe there's something wrong with it):
if (!this.IsPostBack)
{
Utility.HandleReferrer(Request, Response, "Logon.aspx");
Response.Cookies["lastpage"].Value = "Enroll.aspx";
}
and the HandleReferrer method looks like this:
static public void HandleReferrer(HttpRequest request, HttpResponse response, string expectedReferrer)
{
var cookie = request.Cookies["lastpage"];
if (cookie != null && cookie.Value.ToLower().Contains(expectedReferrer.ToLower()))
{
return;
}
response.Redirect("Logon.aspx");
}
So, why in the world does it duplicate this cookie? It doesn't ever seem to create more than two.
I suggest you do one of the following.
First, get the latest glimpse and try again.
If it is still showing 2 cookies with that name then get firebug and/or fiddler and look at it that way. If I had to take a guess I'd say there's either something wrong in glimpse or something wrong in how you are interpreting the results. Perhaps glimpse is showing what cookies existed before and then after the request was processed?
A third option is to simply emit the cookies collection from your own .net code. Something like:
foreach(HttpCookie cookie in request.Cookies) {
Response.Write(String.Format("{0} = {1}", cookie.Name, cookie.Value));
}
and see what happens.
I tried another approach, by creating a method that will return the latest cookie occurrence, this way I'll always get the right data.
This method expect the collection of cookies from Request, and the name of the searched cookie, and returns the latest ticket (the information that is normally encrypted)
private static FormsAuthenticationTicket GetLatestCookie(HttpCookieCollection cookies, string cookieName) {
var cookieOccurrences = new List<FormsAuthenticationTicket>();
for (int index = 0; index < cookies.Count; index++) {
if (cookies.GetKey(index) == cookieName) {
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookies[index].Value);
cookieOccurrences.Add(ticket);
}
}
DateTime oldestTime = DateTime.MinValue;
FormsAuthenticationTicket oldestTicket = null;
foreach (var formsAuthenticationTicket in cookieOccurrences) {
if (formsAuthenticationTicket.Expiration > oldestTime) {
oldestTime = formsAuthenticationTicket.Expiration;
oldestTicket = formsAuthenticationTicket;
}
}
return oldestTicket;
}
Actually my problem is that I'm not able to read a cookie value. It always shows null. My cookie name is intUserId
My C# Code is listed below
HttpCookie myCookie = new HttpCookie("intUserId");
myCookie = Request.Cookies["intUserId"];
I have to read a content value of 52. I'm struggling with this issue.
The cookie information should be name = intUserId and content = 52
After creating the cookie you have to return it to the client. Use:
Response.Cookies.Add(cookie);
I am creating the cookie using the code below, How to read the txtusername value in another page and how to delete the cookie when I click sign out(code for sign out). I am new to programming please help.
string cookiestr;
HttpCookie ck;
tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now,
DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data");
cookiestr = FormsAuthentication.Encrypt(tkt);
ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
if (chkPersistCookie.Checked)
ck.Expires = tkt.Expiration;
ck.Path = FormsAuthentication.FormsCookiePath;
Response.Cookies.Add(ck);
You should never store password as a cookie. That's a very big security threat. To delete a cookie, you really just need to modify and expire it. You can't really delete it, i.e. remove it from the user's disk. Check out this documentation.
Here is a sample:
HttpCookie aCookie;
string cookieName;
int limit = Request.Cookies.Count;
for (int i=0; i<limit; i++)
{
cookieName = Request.Cookies[i].Name;
aCookie = new HttpCookie(cookieName);
aCookie.Expires = DateTime.Now.AddDays(-1); // make it expire yesterday
Response.Cookies.Add(aCookie); // overwrite it
}
You cannot directly delete a cookie, you have to set it to expire before the current date:
if (Request.Cookies["clienDetails"] != null)
{
HttpCookie myCookie = new HttpCookie("clienDetails");
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}
You can read more about it here.
Furthermore I really encourage you to not write your own security but to read up on asp.net membership. More secure and easier to use. As I can see many flaws in your security model. Storing the password in plain text in a cookie is really really bad.
EDIT:
As you now changed your code, you have to do this to remove the cookie:
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName);
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}
FYI this did not work for me using Chrome 69 with the Continue where you left off feature enabled. Similar issue with Firefox. Disabling this feature worked for me.
See
Chrome doesn't delete session cookies
How to delete or expire a cookie in Chrome using Asp.Net
In my case this code worked:
Response.Cookies.Delete("access_token");
return Ok();