Securing an ajax request - ajax

i have a website that uses session cookies for security. it works fine and all, but any ajax requests right now are not secure. example being lets say a user is on a page. they can only get to this page if they are logged in with a session - so far so good. but now the ajax request they ask for is
ajaxpages/somepage.php?somevar=something&anothervar=something
if any other user decides to just go to that link themselves (without a session) they still get the same ajax output that was meant for logged in people.
so obviously im going to have to pass session data across when i send an ajax request. anyone have any tips for the best way of doing this? ive never done this before and would rather use trusted methods than make up my own.

The ajax requests work just like any other request to your website and should return the same session cookies as the non-ajax request. This is pointed out in this question. If you aren't getting the session cookie, perhaps something else is wrong.

Having an ajax output isn't necessarily a vulnerability. It entirely depends on what data is being transmitted. I am not sure what platform you are using, but most web application development platforms have a session variable that can maintain state between requests.
What you should have in place is way of marking the user as being logged in from the server side. I php this would look like:
if(login($user,$password)){
$_SESSION['logged_in']=true;
}
Then you can check in a header file if they are allowed to access the page:
if(!$_SESSION['logged_in']){
header("location: http://127.0.0.1/");
die();
}
(If a variable isn't set it is also false.)
There are a few things you need to keep in mind. This is a vulnerability:
if(!$_COOKIE['logged_in']){
header("location: http://127.0.0.1/");
die();
}
The user can control $_COOKIE, so they can tell you that they are logged in.
Another vulnerability:
if(!$_COOKIE['logged_in']){
header("location: http://127.0.0.1/");
}
header() doesn't kill the script. In fact it still runs, so it will still output but it won't be displayed in a browser, you can still use netcat/telnet/wireshark to see the data.

Use the same security check on the pages that handle the ajax request.

Since that is a PHP page, I don't see why you couldn't perform authentication on the PHP side. If authentication is successful, send back the data. Otherwise, send back an error message. AJAX aren't that different from any other request.

Just let ajax carry the session cookie, there is no problem with that, but you must check if the user is logged or not at the end, and you might want to add some CSRF token for your request, just in case ...
And try to validate the referrer, so you can check if the request was sent from your website, and your website only, it's not a good practice to let user open your request url for ajax in their browser ....
And if you have query in your script, to get some data from your database or else ... don't forget to sanitize the input, and escaping the output, based on what kind of data that you need, once more just in case ...

Related

Golang - Server Side Login Handling - how to resume request after login?

Currently, I’m developing a web app with server-side rendering using the Gin framework and I’m having a problem with login intercepting. When an HTTP GET request hits an endpoint, middleware is used to check the browser cookie and redirect the traffic to the login page. This works fine and after successful login, the user is always redirected to the dashboard page. My question is how I should redirect the user back to the originally requested URI instead of the dashboard page?
Also, a bit more complex scenario is on HTTP POST. It looks like the HTTP POST method doesn’t work quite well with a redirect. Also, how would I resume the request with the same post request after the user successfully login?
Thanks for the help!
For the HTTP GET scenario, this one is easy, you need to remember the original URL somewhere. The are a few ways you could go about this:
Store the URL in session information(if any is available, you do need sessions for non-authenticated users)
Store it in a query string, for example, redirect to example.com/login?original=https%3A%2F%2Fexample.com%2Fanother-page. Your login page can look for the query parameter and include it in the login form or make sure that the action of the login form matches the given URI. On a successful login attempt you can get the original URL form the query param and set it as the Location.
Store the original URL in a cookie, upon successful login you can just check the cookie value and use that.
As for the HTTP POST scenario. If you just want to redirect the same POST request to a different URL you can use a 307 Temporary redirect. A 307 will preserve the request body and method and not turn it into a GET request like a 303 See Other or 302 Found.
Resuming the original POST after showing the login screen and after a successful login is a little more complex. When you redirect to the login page you interrupt the flow of the user, maybe it is better to let the user re-post their request after logging in, instead of doing it for them.
Having said that, it is technically possible. We require two steps, first is storing all the data to recreate the request. Then after login completion we can render a form with this saved data and use javascript to submit the form. By adding:
<script>document.getElementById("myForm").submit();</script>
After your form, the browser will submit the form after loading the javascript, thus recreating the original POST.
The storage part can be done via the server side session or a cookie.

AJAX login redirecting to returned URL (security)

I'm working on AJAX login form. On submit it sends login data to back-end. If there is a problem with login, appropriate response is returned. When login data valid, back-end creates a session for user and sends back a URL where user should be redirected. I want to return URL, because it changes depending on multiple user settings (language, personal/business, etc.).
Am I overlooking any security issues with this approach? Is it possible for attacker to redirect user to malicious website when browser trusts URL returned from AJAX call?
No, that's a pretty standard method for handling login via an asynchronous handler (assuming that you're doing this over HTTPS, if not, all bets are off).
And yes, it is possible for an attacker to redirect a user, if you allow the attacker to set where the redirect goes.
So that means that you should validate any user-inputted (and hence potentially attacker set) URLs that you're going to redirect to make sure they are safe. Basically make sure the URL is on your domain, and make sure that it's a valid URL. You can go deeper (check for XSS style attacks, etc), but you usually shouldn't have to as long as you're practicing good security practices in the rest of the application.
But then again, that's just basic application security Filter-In, Escape-Out. So filter the inputted URL, and you should be fine...

How to block external http requests? (securing AJAX calls)

I want to use post to update a database and don't want people doing it manually, i.e., it should only be possible through AJAX in a client. Is there some well known cryptographic trick to use in this scenario?
Say I'm issuing a GET request to insert a new user into my database at site.com/adduser/<userid>. Someone could overpopulate my database by issuing fake requests.
There is no way to avoid forged requests in this case, as the client browser already has everything necessary to make the request; it is only a matter of some debugging for a malicious user to figure out how to make arbitrary requests to your backend, and probably even using your own code to make it easier. You don't need "cryptographic tricks", you need only obfuscation, and that will only make forging a bit inconvenient, but still not impossible.
It can be achieved.
Whenever you render a page which is supposed to make such request. Generate a random token and store it in session (for authenticated user) or database (in case this request is publicly allowed).
and instead of calling site.com/adduser/<userid> call site.com/adduser/<userid>/<token>
whenever you receive such request if the token is valid or not (from session or database)
In case token is correct, process the request and remove used token from session / db
In case token is incorrect, reject the request.
I don't really need to restrict access to the server (although that would be great), I'm looking for a cryptographic trick that would allow the server to know when things are coming from the app and not forged by the user using a sniffed token.
You cannot do this. It's almost one of the fundamental problems with client/server applications. Here's why it doesn't work: Say you had a way for your client app to authenticate itself to the server - whether it's a secret password or some other method. The information that the app needs is necessarily accessible to the app (the password is hidden in there somewhere, or whatever). But because it runs on the user's computer, that means they also have access to this information: All they need is to look at the source, or the binary, or the network traffic between your app and the server, and eventually they will figure out the mechanism by which your app authenticates, and replicate it. Maybe they'll even copy it. Maybe they'll write a clever hack to make your app do the heavy lifting (You can always just send fake user input to the app). But no matter how, they've got all the information required, and there is no way to stop them from having it that wouldn't also stop your app from having it.
Prevent Direct Access To File Called By ajax Function seems to address the question.
You can (among other solutions, I'm sure)...
use session management (log in to create a session);
send a unique key to the client which needs to be returned before it expires (can't
be re-used, and can't be stored for use later on);
and/or set headers as in the linked answer.
But anything can be spoofed if people try hard enough. The only completely secure system is one which no-one can access at all.
This is the same problem as CSRF - and the solution is the same: use a token in the AJAX request which you've perviously stored eslewhere (or can regenerate, e.g. by encrypting the parameters using the sessin id as a key). Chriss Shiflett has some sensible notes on this, and there's an OWASP project for detecting CSRF with PHP
This is some authorization issue: only authorized requests should result in the creation of a new user. So when receiving such a request, your sever needs to check whether it’s from a client that is authorized to create new users.
Now the main issue is how to decide what request is authorized. In most cases, this is done via user roles and/or some ticketing system. With user roles, you’ll have additional problems to solve like user identification and user authentication. But if that is already solved, you can easily map the users onto roles like Alice is an admin and Bob is a regular user and only admins are authorized to create new users.
It works like any other web page: login authentication, check the referrer.
The solution is adding the bold line to ajax requests. Also you should look to basic authentication, this will not be the only protector. You can catch the incomes with these code from your ajax page
Ajax Call
function callit()
{
if(window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){document.getElementById('alp').innerHTML=xmlhttp.responseText;}}
xmlhttp.open("get", "call.asp", true);
**xmlhttp.setRequestHeader("X-Requested-With","XMLHttpRequest");**
xmlhttp.send();
}
PHP/ASP Requested Page Answer
ASP
If Request.ServerVariables("HTTP_X-Requested-With") = "XMLHttpRequest" Then
'Do stuff
Else
'Kill it
End If
PHP
if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
//Do stuff
} else {
//Kill it
}

Ajax Request for same domain only. Restrict Cross domain ajax

I am new for jquery with limited knowledge.
I am doing ajax request to fetch much imp information to display into the page without reloading the page.
It is done.
But i am worried about. Any can do the call from other server to that php file to get information details.
My Question is that How i can restrict the others to access that file using ajax or directly putting the file path in browser address bar?
Please Help in it.
Thanks in advance.
An ajax request is like any other http request.So you can add the security layer on your server using session-cookies, which will work only if user is logged-in(or you can create dummy sessions for pages that don't expect user to be logged in)
You'll need to include a CSRF token in all your AJAX calls. This prevents CSRF attacks since the attacker cannot put the right token in its submissions.

Using php sessions with ajax (mobile device)

I will explain my problem. I need to know if the steps below are correct:
The user enters their login details and these get submitted to the php server. If these are correct, I want to use the php code to start a session. However, because this is a mobile device I will be using html5 session storage. Now, my mobile website is all ajax based with no page reloads. So if the user submits the correct login credentials, I make an ajax response back to the user with what information? The SID/session_id of the session_start? Then, on the mobile device I place this session_id into the html5 session storage?
So, if these steps are correct, when the user then navigates around the website they are now logged in. And if they want to do something e.g. access a private page this creates an ajax request to the php server... this is where I am stuck. I assume that in this ajax request I send the session_id from the html5 session storage object, how does the php server use this id to prove the user is authentic? Presumably I need some kind of if statement and if it's not satisfied, send an ajax response back which my javascript will interpret as redirecting the user back to the login screen.
Many thanks if anyone can help me, it will be much appreciated as I am very stuck.
Note that cookies are not an option...
You could theoretically use HTML5 local storage to store the session ID, or transmit the session ID as a GET parameter in every request and pass it manually to PHP using session_id(), but I can't see the benefit. You might as well rely on cookies for this - they will be transmitted in Ajax requests.

Resources