Asp.net jquery ajax request.cookies cross domain - asp.net

Due to cross domain issues, I decided to try a new workaround for detecting sessions between 2 of my domains. I assumed this process would work as I wasn't trying to set any cookies, and it works fine in chrome and firefox, but not in IE9.
I have stepped through in debug mode and the aspx page I request has no access to it's own Request.Cookies, whereas it does when I use chrome.
The process is:
On domain1, (an asp.net mvc application) the user logs in. As part of that login process, a cookie is set on that domain. If I then hit a test page on this server, I can see the cookie has been set.
On domain2 (an asp.net webforms app), I make a jQuery.ajax request to that test page on domain1, which is meant to check for the cookie and return an encrypted string.
When stepping through during this request to domain2 when called via ajax I can see the request.cookies collection is not populated. Frustratingly, User.Identity.IsAuthenticated is true, but I can't get access to the cookie I set.
Is this just another example of the whole cross domain security in action? To me it seems even making the ajax call using jsonp and all the other various hheaders etc, isn't going to help in this situation as it appears to be something more than that?

It seems that you're correct in your assumption. JQuery will by default not send cookies if its connected to a domain that is not the same as the domain the page is on.
You can try using the xhrFields from the JQuery API to perform the cross domain call.
$.ajax({
url: a_cross_domain_url,
xhrFields: {
withCredentials: true
}
});
http://api.jquery.com/jQuery.ajax/
Hope that helps!

Related

SignalR cookies not sent from client

I have a cookie which is sent from the client which is used as part of my MVC web service, however now that I have integrated a hub into this application the hub doesnt get sent the cookie, whereas the mvc app does.
Now after reading other similar questions (not that there are many) the cookies domain seems to be to blame, or the path is not set.
Currently my system has 2 web apps, the ui and service. In my dev environment it is like so:
Service
http://localhost:23456/<some route>
UI
http://localhost:34567/<some route>
So in the above example, the ui will send a query to the service, getting an authorisation cookie on the response, which is used elsewhere.
In this example the cookie domain from the service is localhost, as from what I have read and seen on other questions there is no need for a port, it will automatically just allow all ports.
Are HTTP cookies port specific?
SignalR connection request does not send cookies
So it would appear to me that the cookie above has correct domain, and the path is set to /, so it should work. However it doesn't send them in the request from javascript.
My request is a CORS request so I am not sure if there are any quirks around that but all normal jquery ajax calls make it to the server fine with the cookies, any ideas?
OH also my cookies are httponly as well, not sure if this makes a difference...
== Edit ==
Have tried to rule out some stuff, have turned off httponly and it still refuses to send the cookies to the server, I have also noticed a few outstanding cookie issues which mention adding the following code in somewhere to make ajax behave a certain way:
$.ajax({
xhrFields: {withCredentials: true}
})
Tried using that and still no luck, so I am out of ideas.
I raised an issue as there is an underlying issue with < version 2 beta of SignalR relating to CORS and cookies.
https://github.com/SignalR/SignalR/issues/2318
However you can manually fix this issue by appending:
xhrFields: {withCredentials: true}
to all ajax requests within the jquery.signalr-*.js, this will then send cookies over CORS, although I do not know if this has any adverse effects on older browsers or IE.

Authentication in ASP.NET HttpHandler

I have created a HttpHandler to be used with SWFUpload to upload images to the server. This upload is done in an administration backend so users need to be authenticated to upload images.
Initially I made the whole administration area deny annonymous users but because of the way SWFUpload appears to work it wouldn't work correctly with Forms authentication and would return a 302 status code.
I had thought it would be possible to make the location of my handler public in Web.config and use context.User.Identity.IsAuthenticated in my handler to determine if the user is logged in.
My problem: is that context.User.Identity.IsAuthenticated always seems false in the handler after I have logged in. Does anyone have any thoughts on why this might be?
Yes, you'll need to use IRequiresSessionState:
public class CustomGenericHandler : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
//code
}
All your sessions will then be usable in the generic handler.
Hope this helps!
Which browser are you using when testing?
Your solution should work in IE but will fail in FireFox since SwfUpload is Flash based and Flash always send IE cookies to the server since you are logging in (and thereby creating a ASP.NET session cookie) in Firefox but SwfUpload send a different set of cookies.
My problem was specific to some code added to Global.asax to fix SWFUpload cookie bug for non-IE browsers. I had modified the value of the session_cookie_name variable in the Application_BeginRequest event handler to be the same name as I had set in Web.config.
Doing this breaks the functionality across all browsers. The variable value should be left set to its default "ASP.NET_SESSIONID".

PageMethods security

I'm trying to 'AJAX-ify' my site in order to improve the UI experience. In terms of performance, I'm also trying to get rid of the UpdatePanel. I've come across a great article over at Encosia showing a way of posting using PageMethods. My question is, how secure are page methods in a production environment? Being public, can anyone create a JSON script to POST directly to the server, or are there cross-domain checks taking place? My PageMethods would also write the data into the database (after filtering).
I'm using Forms Authentication in my pages and, on page load, it redirects unauthenticated users to the login page. Would the Page Methods on this page also need to check authentication if the user POSTs directly to the method, or is that authentication inherited for the entire page? (Essentially, does the entire page cycle occur even if a user has managed to post only to the PageMethod)?
Thanks
PageMethods are as secure as the handler in which they reside.
FormsAuthentication will protect everything except the Login page.
On an unprotected handler, like login, you should expose only methods that 1) are not sensitive or 2) validate the user.
EDIT: in response to comments and other answers regarding CSRF and XSS please see http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx
You're trying to protect against CSRF attacks.
These attacks can be prevented by requiring an authorization code in the POST parameters, and supplying the auth code in the initial page load. (The auth code should be per-IP address and per-user, and should expire quickly)
For added security, you can make each auth-code only usable once, and have each request return a new auth-code. (However, if any request fails, you'll need to reload the page)
I am working on a project that heavily utilizes ASP.Net WebForms Page Methods which I talk to using Ajax. This is rather very convenient for me than writing all my codes in JavaScript.
However, Securing the page methods became an issue which troubled me. I see that I can access the page methods via Postman and Fiddler hence, enabling hackers to play with your APIs.
My solution was quite simple which I discovered accidentally. Adding a static Cookie request to the page method would return error for any app that is NOT the website.
[WebMethod]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
public static string GetAnything(object dat)
{
HttpCookie myguid = HttpContext.Current.Request.Cookies.Get(Constants.Session.PreventHacking);
var hackguid = myguid.Value ?? ""; //other page method contents
return "anything";
}
A postman request to this method would return :
{
"Message": "There was an error processing the request.",
"StackTrace": "",
"ExceptionType": ""}
While a more detailed error would show if on LocalHost.
I understand there are browser ad-ons that can intercept API calls by sitting just beside the website. I have not tested this. A separate security fix has to be built for this however.
I'll update here once I perform some tests.
Think of Pagemethods like a mini webservie local to the page. The fact is they will have no extra checks and verifications in place except those that are placed on the entire website, and those that you choose to put in.
Using Pagemethods is a smart idea from the point of view of 'Encapsulation', and if you're going to use them it doesn't hurt trying to put in some extra security measures in place.

ASP.NET Membership Force HTTPS on PostBack

I have a login form on the home page of an ASP.NET 3.5 website which for performance reasons needs to be accessed with a standard HTTP connection. Since the normal postback for an ASP.NET page is relative call for the post, it would mean that when the browser posts the values are sent unprotected.
I would like to do one of two things to make this secure:
Force the Postback to be secure to the same page
Send the post to a different page using an HTTPS connection
Is there a way to implement option one?
I'm also looking at the Authentication Service, but looking at the URL reference it is using a relative path:
Sys.Services._AuthenticationService.DefaultWebServicePath = '../Authentication_JSON_AppService.axd';
I don't see a way to override this to put in an HTTP path.
You could use Cross-Page posting:
http://msdn.microsoft.com/en-us/library/ms178139.aspx
You can change the form's action property with javascript to tell it to submit to a different page with https. I have done this and it works nicely.
You could also change it to submit to the same page with https, but I think asp.net would complain about that (not sure - never tried it).
sample script:
document.forms[0].action = "https://www.whatever.com/submit_page.aspx";

session lost on redirect

I have a web app that is being hit by facebook. The login page retrieves the keys that I need and sets some session variables. When the server then redirects the user to the next page, the session information is lost. I’m running the IIS engine on vista ultimate at the moment, the app pools don’t matter because I’m using a state service and I’m still losing the session state. I’ve tried both the overloaded method of the response.redirect function and also adding a header to the page to force the redirect and none of this seems to work. Does anyone have any ideas of what I’m missing?
I’ve tried both of these:
Response.Headers.Add("refresh", "3;url=Dashboard.aspx")
And
Response.Redirect("Dashboard.aspx", False)
[EDIT]
So i just did a little experiment and well it turns out that when I hit the url directly from the facebook page I get the problem, but when i copy the url for the IFrame into a new browser window and try it it works fine.
[EDIT]
So I found an article on this and after addin gthe header the problem was solved (for now)
http://support.microsoft.com/kb/323752
Response.AddHeader("P3P: CP", "CAO PSA OUR")
when I hit the url directly from the facebook page I get the problem, but when i copy the url for the IFrame into a new browser window and try it it works fine.
If you're in an iframe, any cookies you set are “third-party cookies”. Third-party cookies may be subject to more stringent conditions than the normal “first-party” cookies you are setting when the user is directly on your site. This can be due to different browser default cookie handling or because the user has deliberately configured it like that. (And for good reason: many third-parties are unpleasant privacy-invading advertisers.)
In particular, in IE6+ with the default settings, you cannot set a third-party cookie unless you write a P3P policy promising that you will be a good boy and not flog your users' data to the nearest identify thief.
(In practice of course P3P is a dead loss, since there's nothing stopping the site owner from just lying. Another worthless complication that provides no actual security. Yay.)
I'd try running Fiddler and see if your session cookie is being sent properly with the response when interacting with your app via Facebook.
The session depends also on cookie support by the client. When you say the app "is being hit by facebook" are you sure that by what ever means they are "hitting" you they are supporting cookies?
Response.Redirect and refresh don't carry session. Server.Transfer() can but loses the ability to transfer to other servers/sites.

Resources