Tag Archives: ASP.NET MVC Framework

CSP (Content Security Policy)


In this post, I’ll practically show you one promising new defense using CSP (Content Security Policy) that can significantly reduce possible XSS (Cross-Site Scripting) attacks in modern web-browsers (currently Chrome 16+ and Firefox 4+)!

I’ll not only block inline/outer scripts but also ask user-agent to auto-generate report for each violated activity it founds that violates my pre-defined policy.

Read full post:

Exploring CSP (Content Security Policy) using ASP.NET MVC

Test online: http://csp.somee.com/

Cross-Origin requests and ASP.NET MVC


We can initiate cross-domain request in our webpage by creating either XMLHttpRequest object or XDomainRequest object. End user’s web-browser will request data from the domain’s server by sending an “Origin” header with the value of origin. If server responds with an “Access-Control-Allow-Origin:* | Origin” then we are permitted to access data; otherwise response will be unauthorized request.

Because we’ve to handle our server response for allowing cross-origin requests; we’ll use BeginRequest event handler in the Global.asax file for adding “Access-Control-Allow-Origin” header in our response.

HttpApplication.BeginRequest event occurs as the first event in the HTTP pipeline chain of execution when ASP.NET responds to a request. The BeginRequest event signals the creation of any given new request. This event is always raised and is always the first event to occur during the processing of a request.

protected void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext.Current.Response.AddHeader(
                "Access-Control-Allow-Origin", "*");    /* HttpContext.Current.Response.AddHeader(
      "Access-Control-Allow-Origin", 
      "http://AllowedDomain.com"); */
}

Asterisk (*) symbol indicates that request is public; however for the sake of security; we can allow a specific domain. In that case, the server will check whether request’s “Origin” header matches with domain-name that we allowed. So server will block unauthorized requests as soon as possible.

You can validate requests action-level by creating an attribute inherited to “ActionFilterAttribute” and allow only one action method to be accessible from cross-domains.

Support of Cross Browsers

Cross-Origin requests supported on IE8 (Windows 7 version),
Safari 4+
, Chrome and Firefox 3.5+ web-browsers. Preflight or Credential requests are supported on Firefox 3.5+Safari 4+ and Chrome web-browsers; IE8 doesn’t support them. You’ve to use XDomainRequest object for supporting IE8+ for cross-origin requests. IE6 and IE7 are not
supporting cross-origin requests.

For more details: please read Nicholas C. Zakas‘s article: Cross-domain Ajax with Cross-Origin Resource Sharing

Possible Attacks

Same origin used by web browsers
has a most significant protection again attack; however, cross origin requests are mostly vulnerable to attack.

  • CSRF attack: Cross-Site Request Forgery attack. CSRF interacts
    with user credentials and do malicious stuff on behalf of the user. It mostly applied to email accounts.
  • XSS attack: Cross-Site Scripting attack occurs to inject malicious
    data with POST/GET messages.
  • DNS Rebinding attack is interaction with DNS hostnames and networks address. Hacker injects malicious code and executes it; on the server side; server consider hacker’s request as authentic request because hostname matches.
  • Spoofing and re-direction attacks are mostly applied
    to cross-origin requests because server heavily relies upon HTTP headers to determine which site can access resources as well as what action they are permitted to do.

For cross-origin requests’ security: “Ensure user authority cannot be misused or compromised“.

A while ago, I wrote an article “ASP.NET MVC security and hacking: Defense-in-depth“, in which I talked about XSS and CSRF attacks. All of those attacking techniques also apply to cross-origin requests.

There is no definitive way to protect your cross-origin requests however; you can make your requests harder to attack by using some techniques as Google,
Twitter and Facebook are doing with their cross-origin APIs like Twitter‘s tweets APIs; Facebook‘s live stream and comments APIs.

Security consideration when passing data through Ajax request in ASP.NET MVC


Note: Current blog-post is old. You can find latest/new blog post here:

ASP.NET MVC security and hacking: Defense-in-depth

Always be careful when passing data through JSON request because data will be visible to end user and in some cases, secure data can be exposed to end user.

  return Json(new dtweetDataContext().Users);

Above statement is passing the records of all users including users’ passwords.

“User” is a LINQ-to-SQL entity class as shown here:

public partial class User
{
  public string UserName    { get; set; }
  public string FullName    { get; set; }
  public string Password    { get; set; }
  public string Email       { get; set; }
}

Figure shows what happened and how secure data is visible to end user:

img27150

The best way is to pass a few fields of records by using IQueryable<type>.Select(..) extension method as shown here:

return Json(new dtweetDataContext().Users
     .Select(u => new { u.UserName, u.FullName }));

Now I am passing just two fields instead of whole user object:

  1. User name
  2. Full name

Figure shows that now our secure data is protected and also we reduced the size of JSON response:

img04741

Always know what’s happening behind the scene when you build something.

ASP.NET MVC Razor – Separate JavaScript code while taking advantage of full link – as Url.Content() does


Note: Current blog-post is old. You can find latest/new blog post here:

Javascript absolute URL issues

If you are using a free hosting service like aspspider.com, then there is a lot of bad stuff will happen for you when you host your website!

The biggest problem I found when I hosted my website in a free hosting service was absolute URL problem.

In ASP.NET MVC view engine, we can use Url.Content(..) helper method for absolute URL but we cannot use it inside a javascript file.

I came up a solution for using same technique inside separate javascript file.

<script type="text/javascript">
      var domainName = '@HttpContext.Current.Request.Url.Scheme://@HttpContext.Current.Request.Url.Authority';
</script>

Just insert this code snippet inside ~/Views/_ViewStart.cshtml file and use it like this in separate javascript file.

[Note: _ViewStart.cshtml executes before any other views and merged with other views so you don’t have to place above code inside every view.]

Javascript.js [Separate javascript file]:

$.ajax( {
            url: domainName + '/Controller/Action',
            type: 'POST',
            success: {}
});

Handling errors in ASP.NET MVC


The HandleErrorAttribute let us specify how to handle an exception that is thrown by an action method. By default, when an action method with the HandleErrorAttribute throws an exception, ASP.NET MVC displays the “Error.cshtml” view that is located in the “/Views/Shared” folder.

public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
    filters.Add(new HandleErrorAttribute());
}

This filter automatically applies to any action method in any controller so that you don’t have to apply HandleErrorAttribute action or controller level.

If user makes a request for “web.config” file and we know that ASP.NET MVC restricts this request and throws an exception that is uncatchable by HandleErrorAttribute because HandleErrorAttribute just handles errors that are thrown by action methods. So for above case, traditional ASP.NET error window will be displayed. Here is a diagram that shows how HandleErrorAttribute works:

So how to handle errors that are not thrown by any action method means that errors those are unhandled or uncaught-able by HandleErrorAttribute.

It is simple, just create a new file “Error.aspx” in the root of the project and update “web.config” file with this code snippet:

<!-- Unhandled Error Section -->
<customerrors mode="On" redirectmode="ResponseRewrite" defaultredirect="Error.aspx" />

Now, whenever an error thrown by any action method, HandleErrorAttribute are asked to handle it and “Error.cshtml” view will be displayed. In contrast, when an unhandled error will occur that is not thrown by any action method, “Error.aspx” page will be displayed.

If you want to know what unhandled error was and you want to be informed through email, it is simple, just do it:

/* for Sending Error through Email */
protected void Page_Load(object sender, EventArgs e) {
    string subject = "An unhandled Error Message";
    string body = HttpContext.Current.Server.GetLastError().ToString(); 
    subject.SendErrorMessage(body);
}
public static void SendErrorLive(this string subject, string body) {
    WebMail.From = "UserName@live.com";
    WebMail.Password = "password";
    WebMail.SmtpPort = 25;
    WebMail.SmtpServer = "smtp.live.com";
    WebMail.UserName = "UserName@live.com";
    WebMail.EnableSsl = true;
    WebMail.SmtpUseDefaultCredentials = false;
    WebMail.Send("UserName@live.com", subject, body);
}

This technique is for “Error.aspx” page but what for “Error.cshtml” view?

By default, asp.net mvc passes HandleErrorInfo type to the “Error.cshtml” view. This type let us directly get error info as shown here:

@Model.Exception.Message

Or directly send email within the view:

@{
    Model.Exception.Message.SendErrorMessage(Model.Exception.ToString());
}

Now following errors are under your control:

  • Error.cshtml: Errors that are thrown by action methods
  • Error.aspx: Any other kind of errors