ASP.NET

Authentication and Authorization Restrictions

Introduction

One key area in crafting web applications is security.  Are users being properly authenticated and are repeated calls to the server properly secured?

Authentication

Authentication simply means the system knows who you are, ideally with a good amount of confidence. Your system should have a login screen, and on all subsequent requests we should be able to tell who you are.

This is usually done with a 3rd party code library. For direct web requests, you’ll usually have a session cookie attached, and that’ll be tied to session information on the server that includes info about your identity.

(Aside: if you’ve got multiple web servers, you’ll need to make sure either that the user always goes to the same one, or that the session info is shared across the server, or you’re going to have a bad time. But I digress.)

When you’re using a javascript API to run your website, you’ll need to make sure that the API calls you make include some authentication information. A decent way to do that is with a user token that can match up to the logged in user on the back end. It’s also a good idea to make your site use SSL to reduce the chance of that token leaking out.

Now, as it happened, the app I was working on had a javascript front end, but after logging in, subsequent requests had a “user_id” parameter on them that simply said who the logged in user was supposed to be. It was trivial to make requests as anyone I wanted by making calls with different user IDs.

So that was step one of the fix: add an API token system to the project and replace the user ID in all API calls with that token (in case it’s not obvious, the token was a much larger number an highly unlikely to be guessed.)

Authorization

We now had a system that knew, with a decent amount of confidence, that the user making the request was in fact that user. Unfortunately, the user still had a little too much power.

Authentication deals with identifying the user. Authorization is a matter of making sure their actions are allowed. In most cases, this comes down to making sure the object being requested or acting upon belongs to the user. When you add admins and groups to the mix you need to add some nuances, and in some cases “anyone can do anything” is fine, but this app was pretty straightforward and it was mostly a matter of adding some checks to the code to make sure user had the right to do what he was asking.

Cleaning up the mess

Some exploits of insecure code can take a bit of work to apply, but many can be done right in the browser (in this app’s case, some of the attacks were just a matter of changing the URL.) The good news is, once you know what to look for the process of fixing these bugs is pretty mechanical. Recently we came across a production issue, where in the site accessed beyond the DMZ or FireWall had some issue with token it was holding. The URL along with the token was noticed. So when this URL was given to the other users, the page is loaded and logged in with the user contained in the token.

Since the Token is send along with the URL, the token is validated for all except for the origin of the token (with what respect the token was created). in order to validate the token properly, we have added “IP Address” in the role.

string webApiUrl = ConfigurationManager.AppSettings.Get("WebAPIURL");
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + " "));
client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
client.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded; charset=UTF-8");
client.Headers.Add(HttpRequestHeader.Accept, "application/json");
string response = client.UploadString(new Uri(webApiUrl + "/Token"), "username=" + userName + "&password=" + " " + "&grant_type=password&additionalData=" + seed + "&entryPoint=" + fixedEntryPoint);
var tokenResponse = JsonConvert.DeserializeObject<Token>(response);
tokenResponse.UserIP = System.Web.HttpContext.Current.Request.UserHostAddress;
filterContext.HttpContext.Session["Token"] = tokenResponse;
isAuthenticated = true;

 

Token token = (Token)filterContext.HttpContext.Session["Token"];
if (!isAuthenticated)
{
	filterContext.Result = new RedirectToRouteResult(
		new RouteValueDictionary()
		{
		{ "controller", "Account" },
		{ "action", "Login" },
		{ "returnUrl", filterContext.HttpContext.Request.Url }
		});
}

 

 

which compares the current IP Address and IP address used to create the Token. if the IP address don’t match, we are redirecting it to login page. by doing this we are making sure the application is properly secured.

 

 

About The Author

Leave a Reply

*