How to Implement CSRF Guard in ASP.Net - asp.net

I need to implement CSRF(Cross Site Request Forgery) Guard in my code (asp.net).
Though I got a library from OWASP, implementing it is a pain since no documentation is given. Can someone provide me an easier way to implement csrf guard in .net, or configure OWASP library correctly ?
Thanks
-Chandan

ASP.NET MVC
If you're using asp.net mvc you can use the anti-forgery token. Basically in your view you would place the following code:
#Html.AntiForgeryToken()
And on your controller you would put this attribute at the top of the controller:
[ValidateAntiForgeryToken]
public ActionResult Foo()
{
// Foo code
}
What this does is ensures that the user cannot submit the form from a remote site, because they are unable to generate the token. You can also create a token with a salt.
ASP.NET WebForms
For asp.net Webforms you can override the OnInit method and set the ViewStateUserKey to the the session id. Web forms will validate the viewstate with a MAC check thereby acting like an anti forgery token. Because an attacker cannot generate a valid viewstate (since they don't have the ability to generate a valid MAC because they can't put the session id in the viewstate) the MAC will fail. You will have to do this on each page, or create a base class that already overrides oninit and does this.
public partial class Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.ViewStateUserKey = Session.SessionID;
}
}

Related

Are all incoming requests handled by AuthorizeAttribute in ASP.NET MVC?

I am developing a ASP.NET MVC 5 website which uses local STS for authentication.
I subclassed the AuthorizeAttribute to customize authentication/authorization process, added MyAuthorizeAttribute to GlobalFilters.
When user came in without authenticated, MyAuthorizeAttribute.OnAuthorize successfully caught it and create a SignInRequest to redirect to STS. That is what I want.
I observed that when user authenticated successfully and STS redirected user back, user's browser POSTed a SAML token embedded in request body to my MVC web application, this is by design, and I expected MyAuthenticateAttribute could catch this request, so I can extract the token from request body, check and validate it, however, MyAuthenticateAttribute.OnAuthorize() function didn't get called this time, it directly went to controller.
So is there anything wrong? Where should i catch and handle the token POSTed from user? Thanks.
You need to decorate your action method with [Authorize] attribute or if you want authorization to happen for all actions in a controller, then set that attribute on the controller itself.
Also take a look at the usage of [AllowAnonymous] at https://www.codeproject.com/Articles/1008731/Insight-of-ASP-NET-MVC-s-Authorize-Attribute
AuthorizeAttribute is both an Attribute and a IAuthorizationFilter. Attributes don't actually do anything, the MVC framework scans for where this attribute is added and registers it as a filter on the fly.
However, rather than decorating controllers or action methods with it, you could add it as a global filter:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AuthorizationAttribute());
filters.Add(new HandleErrorAttribute());
}
}
By the same token, you can create your own IAuthorizationFilter or subclass AuthorizeAttribute to do whatever you want. If registered globally, it will always run for all actions and then you can use it to do custom authorization of requests globally.

In ASP.NET; How can I login from a remote HTML page into another ASPX page with ASP.NET Membership

I basically need to login into another domain that is using asp.net membership.
If we have an ASP.net web application using ASP.Net Membership on one hand, and
an HTML page from another domain on the other hand.
Is it possible to login into the ASP.NET website via remote HTML page.
I've done this with Coldfusion before but ASP.NET membership is using a server control.
Cheers!
Underneath the Login Server Control, ASP.NET uses a MembershipProvider implementation and Forms Authentication to a user in with ASP.NET Membership. You can replicate these steps without using the Login Server Control, by manually validating the credentials and then attaching the FormsAuthentication cookie to the Response.
Here are some resources that should help you get started:
Understanding the Forms Authentication Ticket and Cookie - MSDN
Explained: Forms Authentication in ASP.NET 2.0 - MSDN
Examining ASP.NET's Membership, Roles, and Profile - 4guysfromrolla
You would also probably benefit from Reflecting on the source of the Login control, so you can gain an understanding the exact sequence of events that happens when a user logs in using the server control. This should make it easier for you to understand how to replicate that functionality for your particular use case.
As a side-note, I would recommend using a custom IHttpHandler implementation as an injection point for processing the login request, but there are many ways you can accomplish this task.
Update, I'm feeling generous, so
Below is an example handler that you could use to log a user in with ASP.NET Membership and FormsAuthentication (just like the server control).
This code assumes:
There is a mapping configured with either Routing or the web.config that will call this handler.
The requesting page has a form that points to the url/route that is mapped in the web.config or with routing, and that the form on that page contains a username input field with the name username and a password input field with the name password.
public class LoginHandler : IHttpHandler
{
void IHttpHandler.ProcessRequest(HttpContext context)
{
string username = context.Request["username"];
string password = context.Request["password"];
if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password) && Membership.Provider.ValidateUser(username, password))
{
FormsAuthentication.SetAuthCookie(username, true);
RenderUserLoggedInResponse(context.Response,username);
}
else FormsAuthentication.RedirectToLoginPage("loginfailure=1");
}
private static void RenderUserLoggedInResponse(HttpResponse response, string username)
{
response.Write(string.Format("You have logged in successfully, {0}!", username));
response.End();
}
bool IHttpHandler.IsReusable { get { return true; } }
}

custom authentication in asp.net

What is the best way to set up authentication against a custom database of users, in ASP.NET? My current setup is not great, and I am sure that there is a better way to do authentication, but all I can find are some articles that are seven or eight years old. My current setup is as follows:
Application uses the Windows username (via Windows Authentication), to work out whether a user is in a database of allowed users. This is done via a call to an Authenticate method in Page_Load.
If the user isn't in the allowed users, then the page redirects to a login screen.
The flaw with this method is that it calls:
Response.Redirect("~/login.aspx", false)
Which executes the entire body of the Page_load method. Is there a better way of doing authentication? Would something like custom Page classes, or HTTPModules do the job?
You could do your check earlier in the request, like in OnInit, or you could do something a little more robust, like implement your own membership provider: MSDN article / Video tutorial
Okay, so this is basically how I done it. I wrote this class that inherits from System.Web.UI.Page. I override the OnInit event and this is where the authentication happens (looks up the Windows username against the database of users). If the user doesn't get authenticated, isTerminating gets set to true, and the OnLoad event only runs if isTerminating is false. I tried leaving a Response.Redirect with the second parameter set to false on its own, but this still ran all the subsequent page events. (even with a call to HttpApplication.CompleteRequest())
public class BasePageClass : Page
{
private bool isTerminating = false;
protected override void OnInit(EventArgs e)
{
isTerminating = !AuthenticationManager.Authenticate();
base.OnInit(e);
}
protected override void OnLoad(EventArgs e)
{
if (!isTerminating)
{
base.OnLoad(e);
}
}
}
I have no idea whether not running the OnLoad event is the best thing to do, but it "seems" to work fine.

Why would User.IsInRole return true, but AuthorizeAttribute not?

I'm securing an ASP.NET MVC 2 application, and I have a user who is in the role "Foo".
This is true:
User.IsInRole("Foo")
But yet, when I attempt to lock down a controller action like the following, the user is denied:
[Authorize(Roles = "Foo")]
public ActionResult PrivatePage()
{
return View();
}
If IsInRole reports true, why would the Authorize attribute not allow the user in?
It could be caused if you are storing persistent cookies for your forms authentication cookie. In that scenario IsInRole may check against the cookie without verifying up to date login.
For future people with a similar problem - it could depend on how you are actually setting up your roles on the current user.
I had a similar issue where the roles were being pulled out of the cookie in an override of OnActionExecuting in a base controller. Turns out this was executing after the [Authorize] attribute, so the roles weren't actually set up when the attribute was checking for them. The call to User.IsInRole, being in the View, was executing after OnActionExecuting, so it saw the roles fine.
So User.IsInRole returned what I expected, but the [Authorize] attribute did not.
I was able to resolve this by moving the code for getting the roles into a more sensible place, that executes before the Authorize attribute - for example, in Global.asax.cs:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
// do stuff in here
}
Or even better, in your own custom attribute - see https://stackoverflow.com/a/5314736/206297.
They should both return true. Have you tried using SQL Profiler to check the queries run against the DB?

Auth Cookie expiration in .Net

I'm working on an app using ASP.Net's form authentication. The client also makes RESTfull calls to the server (ExtJS components on front end).
We are using a custom HttpHandler for the service calls.
My problem is that anytime the anytime the authentication cookie expires my HttpHandler 's ProcessRequest method isn't called in order for me to check for the cookie's absence and redirect the user to log in again.
An example would be a user leaves a page open then comes back in 20 mins and clicks on a dropdown that is loaded asynchronously. The app just hangs never getting to my handler.
Any thoughts?
Highly suggest reading the section entitled "The Pipeline Event Model" in this MSDN magazine article: Securely Implement Request Processing, Filtering, and Content Redirection with HTTP Pipelines in ASP.NET.
In a nutshell, authentication is performed well before the request is handed over to ProcessRequest() in your HttpHandler. If you need to handle these cases, you will need to hook into the pipeline events (such as BeginRequest or Authenticate Request) and add your own handlers, like so:
public class EnableWebServicesModule :
IHttpModule
{
public void Init(HttpApplication app)
{
// register event handler
app.BeginRequest += new EventHandler(this.OnBeginRequest);
}
public void OnBeginRequest(object obj, EventArgs ea)
{
// Check if security works here by looking for the cookie or
// the user context.
}
...
}
For further reading on this fascinating and exciting topic, check Rich Strahl's walkthrough: A low-level Look at the ASP.NET Architecture

Resources