Ajax Authentication Response - ajax

I have a login form that I am considering if it should be 'ajax'ed or not.
The reason I am contemplating this is because if the response of the ajax call is fixed (like 0 for invalid and 1 for valid) I can redirect the ajax request through the javascript console and log into the system maliciously.
Is there a way to solve this security issue?
Is that why all login forms I've seen so far (including here on stackoverflow) are non-ajax?

You need to make sure that all content which should be displayed only to logged-in users should only be transferred after the login process. The server-side should check on every request whether the user is logged in or not. This could be done by traditional methods (like session ids in cookie or post/get).
So in short: don't transfer fixed values but transfer a normal session id which vary from user to user.

You perform your login with ajax.
Server side validates the login and starts a session.
Even if the client ignores the response from the ajax call, it's important that any ajax calls check if the session was properly created when login, and refuse to do what's asked if the session wasn't properly opened at login time.
In PHP (example):
Login:
<?php
header('Content-type: text/json');
session_start();
if ( check_password() ) {
// send ok response
}
else {
// send not ok response
}
// if that session variable exists, then we logged in successfully
$_SESSION['user'] = $user;
other ajax calls :
<?php
header('Content-type: text/json');
session_start();
if ( ! isset($_SESSION['user'] )) {
// send not ok response
// on the client, this will redirect to the login page
exit;
}
$user=$_SESSION['user'];
... rest of the code here
For every ajax call, when the response arrives, you should first check if the response is ok -- up to you to determine how you want this represented.
As an example, a response might look in JSON like
not logged : { "ok":"N","error":"not logged in"}
logged : { "ok":"Y","data":[{"name":"xxxx","age":19},{"name":"yyy","age":91}]}
or { "ok":"Y","data":"Some text"}
etc, etc...
If it's ok, you proceed to handle the response. If not, you can for example redirect to the login page.
Note that with PHP, every ajax call you make includes the session ID automatically (it's a cookie), so PHP knows which session is associated with a particular request.

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.

Extjs 4 Session Management

I am having web based application in which user session has to be managed management.
In app.js I have used launch config as :
launch: function(){
Ext.create('myproject.view.LoginForm')
}
LoginForm : will show log in dialog and invoke login controller for communicating with server for authenticating the credentials provided by the user.
So when ever user refreshes the page Extjs is asking for log in that is because of I am not checking the session in here, How should be the session details stored in Extjs client and check to avoid prompting the log in unless user has log-out ? and How to manage user session ?
User identity and session information must be stored server side. Typically a cookie is set once the user authenticates successfully so as not to prompt the user again. This cookie is sent from the server and is stored in the browser automatically and sent back to the server for inspection on page refresh. Server should validate the cookie if OK allow user to proceed.
Per #existdissolve comments below
In your launch method, simply run a a session check before you create the login form. Whether this is cookie checking or a request directly to the server, the result of the session check can then trigger the creation of the login form, or whatever other logic you have for creating the rest of the application
Session Management can be done using
Inside login controller
// Storing user details in session / cookies
Ext.util.Cookies.set("key", value);
On logout button
// remove user details from cookies
Ext.util.Cookies.set("key", value);
In App.js
autoCreateViewport: false,
launch: function(){
var key= Ext.util.Cookies.get("key");
if (key=== undefined || key== 'null' || key== null || key.length <= 0){
// load login UI as user is not logged in
Ext.create('app.view.LoginForm');
}
else {
// load main UI as user is already logged in
Ext.create("app.view.Viewport");
}
}

Ajax based application and want to redirect to login page after session expired

Here I am make one application which is fully remote based.
only once all js and css loaded. So I want need solution for session expired.
Means when ajax request come to controller, it will be authenticated first, for session if session expired then I want to redirect to login page relogin.
[EDIT - #Brad]
Let's try and clarify your requirement..
1) make request to server via Ajax
2) server responds with HTTP 401, not authorized
3) Ajax recognises 401 status and redirects to Login page
4) login success,
5) then old request executed. means step 1 request executes.
6) but I want dont want to execute that step-1 request but want to execute home page everytime.
One approach is to have your Client side AJAX code check for a HTTP 401 response code which means that your users session has timeout and they are no longer logged in.
Using JQuery...
$.ajax({
type: "post", url: "/SomeController/SomeAction",
success: function (data, text) {
//...
},
error: function (request, status, error) {
// look for status of 401 and redirect to login
}
});
Of course you just have to make sure your web app is returning the appropriate status codes. I found this article on the subject to be thought provoking.
There is also some good information on a similar question
[EDIT]
OK, from your updated question at step 3) this is occuring over an ajax request and I am expecting that your user does not see a login page because your ajax handling code will receive the 401 response and you can decide not to display it. You can then redirect the users browser to your login URL of choice. In this case you would redirect to the home page, or configure your login page to accept an additional URL parameter to tell it where you want the user to be sent to once they have logged in.
You could use a filter interceptor before the request comes on to your action every time.
A better way to do this is by using the apache-shiro authentication plugin available for grails.
See this : Apache Shiro Integration for Grails
Install this in your application and configure it. Its simple and takes care of most of your authentication requirements.

ASP.NET MVC - Failed to load resource in Response.Redirect

I noticed if my session expired whilst on my site and then I clicked on an Ajax.ActionLink, the login page would be displayed in a PartialView. I've created an override of the OnActionExecuting method like so:
protected override void OnActionExecuting(ActionExecutingContext ctx)
{
if (!ctx.HttpContext.User.Identity.IsAuthenticated)
{
if (ctx.RequestContext.HttpContext.Request.IsAjaxRequest())
{
//ctx.RequestContext.HttpContext.Response.RedirectToRoute(new { controller = "Account", action = "LogOn" });
ctx.RequestContext.HttpContext.Response.Redirect(Url.RouteUrl(new { controller = "Account", action = "LogOn" }));
}
}
}
This checks if the User is Authenticated and then if the request is an AjaxRequest. It will then redirect the user to the LogOn method in my Account controller if they're no longer authenticated for an Ajax actionlink. The problem is I get "Failed to load resource" in the console.
This checks if the User is Authenticated and then if the request is an
AjaxRequest. It will then redirect the user to the LogOn method in my
Account controller if they're no longer authenticated for an Ajax
actionlink
Yes, but if you configured your Ajax.ActionLink or Ajax.BeginForm to update some DOM element with the results of the AJAX request using the AjaxOptions, it doesn't really matter if you are redirecting on the server. The AJAX request will simply follow the redirect and insert the resulting HTML you redirected to (/Account/LogOn) inside the DOM element.
So redirecting from an AJAX request won't solve your problem. As you know the whole point of an AJAX request is to stay on the same page (the address bar never changes).
If you wanted to handle the authentication cookie expired condition in a proper way within your AJAX requests you will have to perform the redirect on the client (using window.location.href). In order to achieve that you may take a look at the following blog post in which Phil Haack exposes a great technique allowing your server to send a 401 HTTP status code in this case instead of redirecting. Then on the client you could intercept this code (by subscribing to a global AJAX handler for example) and redirect to the logon page from the client.

Securing an ajax request

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 ...

Resources