Retrieving cookies from HttpResponse - c#

I have a controller action that I call via Ajax in which I set a cookie like this:
Response.Cookies["Notifications"].Value = "false";
Response.Cookies["Notifications"].Expires = DateTime.Now.AddYears(1);
In another controller action I am checking for this cookie like this:
if(Request.Cookies["Notifications"] != null &&
Request.Cookies["Notifications"].Value =="false")
//Do something here
The problem is that Request.Cookies["Notifications"] is always null. I have verified that the cookie is getting set via FireBug. I'm testing this via visual studio's web built in web server.

The problem was with the fact that I was also setting this:
Response.Cookies["Notifications"].Secure = true;
And of course the cookie isn't being sent because I'm not using Https.

When in FireBug do you see the cookie sent back in the request? Also you can have a look at raw request to see if it is actually there

Just an idea/advice... You could fire Fiddler to sniff the actual http traffic and see how and if the cookies are being transferred in the http headers

Related

User Added Value to HttpContext Request/Response Header being removed

I am having some trouble adding a value to the Page.Request & Page.Response headers and have the key & value stay/persist through a redirect.
I have an enum tracking code that I want to place in the headers to trace how a user goes through my site prior to their checkout.
I am using this code to add the headers to response and request context.
var RequestSessionVariable = context.Request.Headers["SessionTrackingCode"];
if (RequestSessionVariable == null)
{
context.Response.AddHeader("SessionTrackingCode", ((int)tracker).ToString());
context.Request.Headers.Add("SessionTrackingCode", ((int)tracker).ToString());
}
else
{
if(!RequestSessionVariable.Contains(((int)tracker).ToString()))
{
RequestSessionVariable += ("," + ((int)tracker).ToString());
context.Request.Headers["SessionTrackingCode"] = RequestSessionVariable;
context.Response.Headers["SessionTrackingCode"] = RequestSessionVariable;
}
}
The method call that occurs in Page_Load of the necessary controls within the website:
trackingcodes.AddPageTrackingCode(TrackingCode.TrackingCodes.ShoppingCart, this.Context);
The header SessionTrackingCode is their but after a Response.Redirect("~/value.aspx") the RequestSessionVariable is always null. Is there something that happens on the redirect that will wipe out the headers that I add? Or what am I doing wrong on the addition of the header key and value?
this equals:
public partial class Cart : System.Web.UI.UserControl
Headers send by client on every request, so any redirect will require client to send headers again.
Unless you are using some special client (not a browser) any special headers will be essentially ignored/lost during requests. Browser only will send known headers (cookies, authentication, referrer) in requests and act on other set of known headers in response (setCookies). You are using custom header that not known to browser so browser will not read in from response nor send it in request.
Your options:
switch to use cookies for your tracking (same as everyone else)
use AJAX requests to send/receive custom headers (probably not what you are looking for as urls look like regular GET/POST ones)
build custom client that will pay attention to your headers (purely theoretical, unless you building some sort of sales terminal no one will install your client to visit your site)
Note: adding headers to request in page code does no make much sense as request will not be send anywhere (it is what come from browser).
This looks like a job for cookies, rather than http headers. The browser will not return your custom headers to you, but it will return your cookies.

How to ensure a url is called from my application and not manually from browser

I have an application that contains a button, on click of this button, it will open a browser window using a URL with querystring parameters (the url of a page that i am coding).
Is there a way to ensure that the URL is coming from my application and only from my application - and not just anyone typing the URL manually in a webbrowser?
If not, what is the best way to ensure that a specific URL is coming from a specific application - and not just manually entered in the address bar or a web browser-
Im using asp.net.
You can check if the request was made from one of the pages of your application using:
Request.UrlReferrer.Contains("mywebsite.com")
That's the simple way.
The secure way is to put a cookie on the client containing a value encrypted using a secure key or hashed using a secure salt. If the cookie is set to expire when the page is closed it should be impossible for someone to forge.
Here's an example:
On the pages that would redirect to the page you are trying to protect:
HttpCookie cookie = new HttpCookie("SecureCheck");
//don't set the cookie's expiration so it's deleted when the browser is closed
cookie.Value = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Session.SessionID, "SHA1");
Response.Cookies.Add(cookie);
On the page you are trying to protect:
//check to see if the cookie is there and it has the correct value
if (string.IsNullOrEmpty(Request.Cookies["SecureCheck"]) || System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Session.SessionID, "SHA1") != Request.Cookies["SecureCheck"])
throw Exception("Invalid request. Please access this page only from the application.");
//if we got this far the exception was not thrown and we are safe to continue
//insert whatever code here
There's no reliable way to do this for a GET request, nor is their any reason to try for a legitimate user. What you should do instead is ensure that regardless of where the request comes from the user has the proper permissions and access rights and that the session is protected appropriately (HTTP only cookies, SSL, etc.) If the request is changing data, then it should be a POST, not a GET, and it should be accompanied by some suitable cross-site request forgery prevention techniques (such as a cookie containing a nonce that is verified against a matching nonce on the form itself).
There is no way, other than rejecting the request if it doesn't contain a previously generated random one-time token in the parameters (that would be stored in the session, for example).
While there is no 100% secure way to do this, what I am suggesting might at least take care of your basic needs.
This is what you can do .
Client: Add a HTTP header with an encoded string that is like hash (sha256) of some word.
Then make your client always do a POST request instead of GET.
Server: Check the HTTP Header for encoded string. Also make sure it is a POST request.
This is not 100% as ofcourse someone smart enough could figure out and still generate a request, but depending on your need you might find this enough or not
You can check the referer, the user agent, add an additional header to the request, always do post requests to that url. However, considering HTTP is transmitted in plain text, somebody is always able to let wireshark or fiddler run, capture the HTTP packets and recreate the requests with your measures in place.
Pass parameters from your application so that you can verify on the server side.
I suggest you use an encryption algorithm and generate random text using a password(key). Then, decrypt the param on the server side and check if it matches your expectation.
I am not very clear though. sorry about that, If had to do something like this, then, I would do something similar to mentioned above.
You can use to check the header on MVC controller like Request.Headers["Accept"]; if it is coming from your code in angularjs or jquery:
sample angularjs like this:
var url = ServiceServerPath + urlSearchService + '/SearchCustomer?input=' + $scope.strInput;
$http({
method: 'GET',
url: url,
headers: {
'Content-Type': 'application/json'
},.....
And on the MVC [HttpGet] Action method
[HttpGet]
[PreventDirectAccess]//It is my custom filters
// ---> /Index/SearchCustomer?input={input}/
public string SearchCustomer(string input)
{
try
{
var isJsonRequestOnMVC = Request.Headers["Accept"];//TODO: This will check if the request comes from MVC else comes from Browser
if (!isJsonRequestOnMVC.Contains("application/json")) return "Error Request on server!";
var serialize = new JavaScriptSerializer();
ISearch customer = new SearchCustomer();
IEnumerable<ContactInfoResult> returnSearch = customer.GetCustomerDynamic(input);
return serialize.Serialize(returnSearch);
}
catch (Exception err)
{
throw;
}
}

Problem saving/getting cookies in MVC 2

Try to save them like this:
HttpCookie latcook = new HttpCookie("latitude", lat.Value.ToString());
HttpCookie lngcook = new HttpCookie("longitude", lng.Value.ToString());
Request.Cookies.Add(latcook);
Request.Cookies.Add(lngcook);
Everything has a value, and the code steps through without error.
Then immediately after those are set, I refresh my page and step through this:
HttpCookie latcook = Request.Cookies.Get("latitude");
HttpCookie lngcook = Request.Cookies.Get("longitude");
The latcook and lngcook variables have names, but no values. What am I doing wrong?
You are adding your cookies to the request object. They should be added to the response:
Response.Cookies.Add(latcook);
Response.Cookies.Add(lngcook);
Cookies added to the response are returned to the user's browser via a series of Set-Cookie HTTP headers. They are then subsequently sent back (upon the next request) via the Cookie HTTP header. (You should be able to watch this happen using Firebug, etc.) Ultimately, this header will be parsed and populate the Request.Cookies collection.

HTTPS Redirect Causing Error "Server cannot append header after HTTP headers have been sent"

I need to check that our visitors are using HTTPS. In BasePage I check if the request is coming via HTTPS. If it's not, I redirect back with HTTPS. However, when someone comes to the site and this function is used, I get the error:
System.Web.HttpException: Server
cannot append header after HTTP
headers have been sent. at
System.Web.HttpResponse.AppendHeader(String
name, String value) at
System.Web.HttpResponse.AddHeader(String
name, String value) at
Premier.Payment.Website.Generic.BasePage..ctor()
Here is the code I started with:
// If page not currently SSL
if (HttpContext.Current.Request.ServerVariables["HTTPS"].Equals("off"))
{
// If SSL is required
if (GetConfigSetting("SSLRequired").ToUpper().Equals("TRUE"))
{
string redi = "https://" +
HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToString() +
HttpContext.Current.Request.ServerVariables["SCRIPT_NAME"].ToString() +
"?" + HttpContext.Current.Request.ServerVariables["QUERY_STRING"].ToString();
HttpContext.Current.Response.Redirect(redi.ToString());
}
}
I also tried adding this above it (a bit I used in another site for a similar problem):
// Wait until page is copletely loaded before sending anything since we re-build
HttpContext.Current.Response.BufferOutput = true;
I am using c# in .NET 3.5 on IIS 6.
Chad,
Did you try ending the output when you redirect? There is a second parameter that you'd set to true to tell the output to stop when the redirect header is issued. Or, if you are buffering the output then maybe you need to clear the buffer before doing the redirect so the headers are not sent out along with the redirect header.
Brian
This error usually means that something has bee written to the response stream before a redirection is initiated. So you should make sure that the test for https is done fairly high up in the page load function.

Getting the location from a WebClient on a HTTP 302 Redirect?

I have a URL that returns a HTTP 302 redirect, and I would like to get the URL it redirects to.
The problem is that System.Net.WebClient seems to actually follow it, which is bad. HttpWebRequest seems to do the same.
Is there a way to make a simple HTTP Request and get back the target Location without the WebClient following it?
I'm tempted to do raw socket communication as HTTP is simple enough, but the site uses HTTPS and I don't want to do the Handshaking.
At the end, I don't care which class I use, I just don't want it to follow HTTP 302 Redirects :)
It's pretty easy to do
Let's assume you've created an HttpWebRequest called myRequest
// don't allow redirects, they are allowed by default so we're going to override
myRequest.AllowAutoRedirect = false;
// send the request
HttpWebResponse response = myRequest.GetResponse();
// check the header for a Location value
if( response.Headers["Location"] == null )
{
// null means no redirect
}
else
{
// anything non null means we got a redirect
}
Excuse any compile errors I don't have VS right in front of me, but I've used this in the past to check for redirects.
On HttpWebRequest you can set AllowAutoRedirect to false to handle the redirect yourself.
The HttpWebRequest has a property AllowAutoRedirect which you can set to false (it is always true for WebClient), and then get the Location HTTP header.
Also, for someone who just needs the new location, HttpResponseMessage has a RequestMessage property. Sometimes it can be useful, because WebClient doesn't support changing the AllowAutoRedirect property once it's been set.

Categories

Resources