Stop Direct Page Calls to Ajax Pages - asp.net

Is there a "clever" way of stopping direct page calls in ASP.NET? (Page functionality, not the page itself)
By clever, I mean not having to add in hashes between pages to stop AJAX pages being called directly. In a nutshell, this is stopping users from accessing the Ajax pages without it coming from one of your websites pages in a legitimate way. I understand that nothing is impossible to break, I am simply interested in seeing what other interesting methods there are.
If not, is there any way that one could do it without using sessions/cookies?

Have a look at this question: Differentiating Between an AJAX Call / Browser Request
The best answer from the above question is to check for a requested-by or custom header.
Ultimately, your web server is receiving requests (including headers) of what the client sends you - all data that can be spoofed. If a user is determined, then any request can look like an AJAX request.
I can't think of an elegant method to prevent this (there are inelegant and probably non-perfect methods whereby you provide a hash of some sort of request counter between ajax and non-ajax requests).
Can I ask why your application is so sensitive to "ajax" pages being called directly? Could you design around this?

You can check the Request headers to see if the call is initiated by AJAX Usually, you should find that x-requested-with has the value XMLHttpRequest. Or in the case of ASP.NET AJAX, check to see if ScriptMAnager.IsInAsyncPostBack == true. However, I'm not sure about preventing the request in the first place.

Have you looked into header authentication? If you only want your app to be able to make ajax calls to certain pages, you can require authentication for those pages...not sure if that helps you or not?
Basic Access Authentication
or the more secure
Digest Access Authentication
Another option would be to append some sort of identifier to your URL query string in your application before requesting the page, and have some sort of authentication method on the server side.

I don't think there is a way to do it without using a session. Even if you use an Http header, it is trivial for someone to create a request with the exact same headers.
Using session with ASP.NET Ajax requests is easy. You may run into some problems, like session expiration, but you should be able to find a solution.
With sessions you will be able to guarantee that only logged-in users can access the Ajax services. When servicing an Ajax request simply test that there is a valid session associated with it. Of course a logged-in user will be able to access the service directly. There is nothing you can do to avoid this.
If you are concerned that a logged-in user may try to contact the service directly in order to steal data, you can add a time limit to the service. For example do not allow the users to access the service more often than one minute at a time (or whatever rate else is needed for the application to work properly).
See what Google and Amazon are doing for their web services. They allow you to contact them directly (even providing APIs to do this), but they impose limits on how many requests you can make.

I do this in PHP by declaring a variable in a file that's included everywhere, and then check if that variable is set in the ajax call file.
This way, you can't directly call the file ever because that variable will never have been defined.

This is the "non-trivial" way, hence it's not too elegant.
The only real idea I can think of is to keep track of every link. (as in everything does a postback and then a response.redirect). In this way you could keep a static List<> or something of IP addresses(and possible browser ID and such) that say which pages are allowed to be accessed at the moment from that visitor.. along with a time out for them and such to keep them from going straight to a page 3 days from now.
I recommend rethinking your design to be sure that this is really needed though. And also note IPs and such can be spoofed.
Also if you follow this route be sure to read up about when static variables get disposed and such. You wouldn't want one of those annoying "your session has expired" messages when they have been using the site for 10 minutes.

Related

Is there a way using ASP.NET to always run some server side code when a user leaves a page?

I was wondering if there is any way to always run some server side code when a user leaves a page in ASP.NET. The page Unload event is no good because that doesn't get called if someone clicks on a link. Ideally I'd also like the code to run even if the user closes the browser.
I suspect what I'm asking isn't possible, but it doesn't hurt to ask
Problem is, HTTP is a stateless protocol, so when the page has finished being served, you wont know if the user is still on the page or not.
The only way to acheive this would be a hidden piece of Javascript that constantly pings the server with it's session ID, or another similar mechanism. When the ping becomes unresponsive you can reasonably assume the page is not being viewed by the user anymore.
Here is a diagram that explains traditional HTTP message flow.
im not really sure if you can do that but i have a workaround in mind.
There is an event in the DOM called onbeforeunload. it get calls everytime a user leaves a page. you can try sending an ajax request to the server from this function.
The closest thing you can come without creating too messy a solution is to enable ASP sessions. This will create a session on the server for each visitor, who will be identified by a cookie.
After a certain amount of inactivity from the visitor, the session will be closed, and a SessionEnd event will be raised. This you can hook up to in the Global.asax file.
I will not recommend this however, because HTTP is pr. definition a session-less protocol, and using server based sessions violates this fact, and are often problematic. Many solutions that use server based sessions run into problems when the user uses the browser-back button, and resubmits a form. Because the content of the submitted form no longer corresponds the data that exists in the server session.
Also, enabling server based sessions seriously hurts the scalability of the application.
Not that I know of. You'll need to use javascript for that, and call a web service on the server side.

Mixing JQuery Ajax with ASP.NET : is there any security risk

I am using jQuery with ASP.NET in a project. Instead of using ASP.NET Ajax, I am using jquery's ajax functions. Is there any security risk if I do that? I mean, since I am using jquery's ajax calls, no view state information will be passed to the server so that it can verify the page's authenticity (though it saves a lot of bandwidth..).
I would also like to know what is the best/good practice here.
Microsoft has included Jquery in their Visual Studio releases (see: http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx)
If there was a big security risk they probably wouldn't have done that ;)
As with al webapplications never trust the input you recieve. It doesn;t matter if you're working with ASP.Net AJAX, Jquery or any other library. Web requests can always be spoofed. Therefor always sanitize the input you recieve and make sure that the user is authenticated (ASP.Net forms authentication uses cookies and not viewstate).
Make sure that you validate all user input. And post basic authentication information to your Web Services (jQuery.ajax has a data parameter), so that no one can use the services without being a part of the system.
Passing along a session GUID and thus providing the Web Service with full authentication, is enough security for most applications (in addition to normal security checks such as input validation). You may specify closer what security level your application needs.
I use the same practice on many case - jQuery ajax on aspx pages
You can check 3 thinks (select 1-2 of them) and be sure that none can create troubles on your site.
Send all the post data encrypted (if you can).
Send hash value with the post data - and check for the correction of the hash (if you can).
Check that the calls is coming from your host on url.
eg, you have a page 'http://www.yourhost.com/askforajax.aspx',
check if the url starting with the 'http://www.yourhost.com/'
The hash I mean here, must be your implimation of hash or crc check or what ever you like you can call it.
here is a real ajax call from my pages
doSomeWork.aspx?plist=36&pslst=1&e=1202638085&er=12585795
The last 2 parametres are check parametres.
Also inside the the ajax page that make the calculations check every parameter for be correct.
I also check some other thinks in some cases, for example if a user press a button that make a change somewhere this user must have cookies enabled, so I check if the users cookie hash is the same.
For the url check
I belive that the Request.ServerVariables["HTTP_REFERER"], can do the work of checking from where the request come from.
HTTP_REFERER Returns a string containing the URL of the page that referred the request to the current page using an tag. If the page is redirected, HTTP_REFERER is empty
Hope this help you.

Is there conditional caching in ASP.NET?

Is there a built-in asp.net way to conditionally serve pages, for example I want the following logic:
If there is a session data I generate
a page, if there is no session data I
serve the cached page.
I am only interested in knowing about a built-in asp.net mechanism for this. If it does not exist I am probably going to simply cache my page manually and decide whether to serve it or not for each request, based on the session data availability.
I don't think there is built-in support (like varyByParam) for generating fresh output for users with Session Data.
As you suggest, I would recommend manually caching the pages. I would probably determine the user's Session state in the PreRequestHandlerExecute event handler in the Global.asax and then maybe set:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
At the risk of karmabombing, I really don't like this approach to caching.
For me if a GET request is made, then a server should respond to that in good faith. Caching at a page level should be controlled by http headers because the primary goal is not to get the redundant request at all - you don't want to allocate server/bandwidth resources full stop.
Caching objects which are resources involved in making up a page I can totally get behind, but I can't see great arguments for caching a page wholesale.
Respect the headers.
You might want to look at the substitution control (Link) new in .NET 2.0, however it might not be exactly what you are after.

Is there a possible "race condition" when using Asp.Net MVC TempData across a redirect?

When using TempData, my understanding is that it will keep whatever you put in it around for only one request. So when using TempData to retain data across a redirect (in order to use the Post-Request-Get pattern), isn't it possible that some other request from the user could come into the server in between the response sending the redirect and the user's browser requesting the redirected-to page? In which case the get would no longer have the TempData available, correct?
Now, I understand that something like that happening would be very rare, but taking into consideration that the user might have another page open in another tab, and there might be either ajax or timed callback requests occuring on that page, it suddenly doesn't seem all that impossible to me. Is it just generally considered to be too remote to worry about, or am I misunderstanding something?
Edit: To be more specific about the scenario I was asking about.
In Tab 1 the user browses to a page
with a post form
In Tab 2 the user browsers to another page on the site that does
ajax callbacks on a timer
In Tab 1, the user posts the form to the server
When the server receives the post, it saves some data in TempData
and sends back a redirect response
In tab 2, the timed ajax callback happens, sending a GET request to the server. The TempData is removed from the session
In tab 1, the browser receives the redirect and issues a GET request
The server processes the GET request and looks for the TempData, but it's not there anymore
Well, browsing the ASP.NET MVC code shows that the while TempData is stored in the session, it is removed from the session when it is loaded. And it gets loaded in the Controller's ExecuteCore() method.
So I think that would mean that yes, you entirely could run into a race condition where a request from a different browser tab (you had a pretty good example) could cause this problem. But that would depend on each browser's model for handling requests. A browser might serialize all requests to the same server so that only one executes at a time. In reality, they won't do that, though, they'll cap it at the max which is (I think) 5 concurrent requests to the same server.
Given that an ASP.NET MVC site could be services requests to any browser (it's the web, afterall :) ) it is a real scenario, albeit probably a rare one, as you said.
It is entirely possible to have a race condition when using TempData. However, you'd have to of course be "unlucky" to experience it under normal usage. In order to run into the race condition the following must all be true:
You have to be using TempData to begin with.
You have to have multiple browser windows/tabs/whatevers open and sharing the same browser session.
A request from the second browser tab has to "sneak in" between the request and response of the first browser tab.
Note that item #2 depends a lot on which browser you're using. Depending on how you have IE set up, just because you have multiple windows opened does not mean that they share browser cookies, and thus they do not necessarily share sessions (which are based on cookies).
However, there is no race condition in the sense that something explodes if you run into it. That might be what Haacked is refering to. But you can hit a race condition in the sense that you set some TempData in one request and then didn't get it back in the next request where you thought you were going to get it. It'll just be empty.
Thanks,
Eilon
TempData makes use of the Session object, which does not suffer this problem, AFAIK. Have you run into a specific problem with this?
I think it will be never happen,though at beginning I have the same confusion.Think about that if you run your mvc web application in debug mode,then you set a break point in a redirect action .And you give tempdata a value ,then you'll get the tempdate in redirect viewResult and the other view,you will found that the other request never be responsed until the redirect action completed .So what's mean?It said that the mvc application run in single thread mode,it can process a single request in one time.So the scenario above you mentioned can never happen.

Changing credentials on client-side for Basic Authentication on Flex

I want to let the user automatically re-login in my Flex app, which uses Basic Authentication
By the way, I have noted this StackOverflow question, which is relevant, but does not address the question of logging out client-side.
For example, after user A logs in, user B comes to the browser, goes to the login screen (perhaps in a new tab) and logs in.
This should mean that I send user B's credentials in the HTTP headers, and that since these are different from user A's, the server notes the fact and creates a new and separate session.
However, Flex's HTTP proxy catches the header and actually ignores these new credentials.
Flex does offer a way to tell the server to logout, and the Flex login code could invoke this every time before sending credentials, but that seems like an ugly workaround. I want to be able to do this client-side. I could also use a non-standard header for Basic Authentication (since I control the server-side Authentication as well), but that also seems like an ugly workaround.
Is there some way to simply end the session on client-side from Flex code? This is possible from JavaScript, for example.
And is there a way to directly work with cookies at client-side, as I can in JavaScript?
I understand that some of the limitations may be caused by security considerations, but all my communication is to the "home" server, so it should be possible to avoid the restrictions.
You're sort of asking a couple of different questions here.
You can't actually end a basic-auth "session" manually per se (at least not to the best of my knowledge); at best, you can authenticate against a kind of variable basic-auth realm, which may or may not work for you, but otherwise, you're sort of stuck with the first-authenticated session for the duration of the browser instance. Generally not the best way to go, unless you're pretty sure the user owns the machine, or can be depended on to close the browser after each session.
That leaves at least two other options, then. The first is to send in your credentials with an URLRequest object (the post you cited, which I wrote, shows how to do that), and to have your HTTP response hand back something indicating the credentials were accepted -- e.g., a GUID, maybe, generated and stored in some session table (in the database sense) on the server, perhaps. Then on successive HTTP requests, you might send along that GUID in an HTTP header, or as a value in each GET or POST request (similarly to the way Facebook handles their API clients, for instance), check the timeliness of that value on the server, and if all's well, carry on. To "log out," then, you'd simply send in a request to invalidate that GUID, perform the necessary cleanup on the server and inside your Flex app, and all should be fine: the next user can sit down, log in, authenticate, and the process continues.
Another way would be to work with cookies directly. The cookie mechanisms are actually handled mostly for you in Flex, though, since everything gets passed back and forth by the browser on your behalf. For example, if you send in a URLRequest with a username and password, and the server responds with a cookie of any kind, each request you make thereafter will package and send the same cookie, so in most cases, all you need to do is parse the initial response from the server (to set the state of your Flex app), assume the continued presence of the cookie, and when it's time to log out, send a URLRequest to log out, kill the cookie on the server, on status=200 do your Flex-app cleanup, and so on. Accessing the cookie values directly isn't the easiest thing in the world, though; you can use ExternalInterface as a proxy to JavaScript (examples of this online and here on SO, I'm sure), and get at them that way, but there's a good chance you don't even have to do that.
Hopefully that helps. Good luck!
Note also this post, which details some of the incredible distortion that Flex adds to HTTP Requests.

Resources