Monthly Archives: September 2013

Providing Core Functionality Lacking in Entity Framework.

Overview

Download the code on GitHub

Install with NuGet.

Entity Framework provides a very versatile data-persistence API, but like any ORM, it’s not without drawbacks. Recently, during a performance review of a .NET-based web application, I noticed several drawbacks attributable to EF.

EF doesn’t provide batch-processing support. Let’s say I have a class as follows:

class Person {
    public string FirstName { get; set; }
    public string Surname { get; set; }
}

class Team {
    public List<Person> Members { get; set; }
}

class MyClass {
    public void Run() {
        var team = new Team {
            Members = new List<Person> {
                new Person {FirstName = "Paul", Surname = "Mooney"},
                new Person {FirstName = "Some", Surname = "OtherGuy"}
            }
        };
    }
}

Entity Framework will invoke a separate SQL command for each Team Member – teams with thousands of members will incur a round trip to the DB for each member. The solution is provided in the SQLBatchBuilder class. This class allows you to batch such commands in a single command, persisting your data to the DB while maintaining optimal performance by minimising the number of round-trips to 1. The framework also contains a handy LINQ-style SQL command builder, adhering to the functional programming model.

Consider the above example. Let’s say we wanted to create a Team object, which consists of a single entry in a SQL table. The generated SQL would look something like this:

insert into dbo.team (id, name) values (1, ‘My Team’);

Nothing unusual here. But what if the team has 50 Members? That’s 50 round-trips to the DB to create each Member, plus 1 round-trip to create the Team. This is quite excessive.

What if we were building an application that saved customer invoices, or sombody’s Facebook friends? This could potentially result in thousands of round-trips to the DB for a single unit-of-work.

SQLBuilder provides a simple, but effective solution to this:

class Person {
    public string FirstName { get; set; }
    public string Surname { get; set; }
}

class Team {
    public List<Person> Members { get; set; }
}

class MyClass {
    public void Run() {
        var team = new Team {
            Members = new List<Person> {
                new Person {FirstName = "Paul", Surname = "Mooney"},
                new Person {FirstName = "Some", Surname = "OtherGuy"}
            }
        };

		List<SQLBuilder> builders = new List<SQLBuilder>();

		foreach(var member in Team.Members) {
		    var sqlBuilder = new SQLBuilder(connectionString, SQLCommandType.Scalar);
			sqlBuilder.Insert(@"dbo.member", new List<string> {@"FirstName", @"Surname"}, member.FirstName, member.Surname);
			builders.Add(sqlBuilder);
		}

		sqlBatchBuilder = new SQLBatchBuilder(connectionString, SQLCommandType.Scalar, builders);
		sqlBatchBuilder.Execute();

		Console.WriteLine(sqlBatchBuilder.Result);
    }
}

In the above sample, we initialise a list of SQLBuilders. Each builder encapsulates a single insertion statement associated with each Member. Once we’ve looped through all members, we attach the list of SQLBuilders to a SQLBatchBuilder instance, which parses each SQLBuilder’s raw SQL and formats a single command comprised of each insertion statement. This is then executed as a single transaction, resulting in a single round-trip.

The SQLBuilder class itself supports the SQL language itself, allowing clauses, parameters, etc., to be applied:

    builder = new SQLBuilder(connectionString, SQLCommandType.Reader);

    builder.Select(@"Member.FirstName", @"Member.Surname")
           .From(@"Member");
		   .InnerJoin(@"Team", @"Member", @"Member.TeamId", @"Team.TeamId")
		   .Where(@"Member", @"Surname")
		   .EqualTo(@"Mooney");

	builder.Execute();

More updates to follow, including an in-depth analysis into the LINQ-style SQLBuilder.

Connect with me:

RSSGitHubTwitter
LinkedInYouTubeGoogle+

Leveraging the Encrypted Token Pattern

Overview

Download the code on GitHub

CSRF attacks involve leveraging user’s authenticated state in order to invoke malicious attacks, with the general purpose of manipulating data. There are two established approaches designed to prevent such attacks:

  1. Synchronizer Token Pattern
  2. Double-Submit Cookie Pattern

For more information on these, please visit the following resource:

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

Both approaches succeed in preventing CSRF attacks, while introducing architectural and security consequences. Below is a brief synopsis.

Synchronizer Token Pattern

This pattern is recommended by owasp.org as the method of choice in preventing CSRF attacks, and is leveraged by CSRFGuard. While successfully preventing CSRF attacks, it introduces an architectural concern, in that the framework requires session state on web servers. This incurs two issues:

  1. Session-state costs memory
  2. Sessions result in an imbalance in terms of load distribution across web servers

While sessions generally cost a nominal amount of memory, significant user-load can exponentially increase that memory footprint. In general, it is best-practice to avoid sessions. More importantly, if a user has an active session on a specific web server, load-balancers will generally route that user’s subsequent requests to that specific server instead of distributing requests evenly. This results in over-utilization of that server and potential underutilization of adjacent servers. This feature can be disabled on load-balancers (generally), however doing so will result in associated sessions created on more than one web server for a specific user. This will cause synchronization issues, and require implementation of a session management tool to avoid loss of cached data across web servers.

Double-Submit Cookie Pattern

This pattern is a more lightweight implementation of CSRF-protection. While relatively new and generally considered somewhat untested (it’s just as effective as the Synchronizer Token Pattern in my opinion; the arguments against it are weak at best), it achieves protection while avoiding the use of state. The implementation of this pattern, like the Synchronizer Token Pattern, produces design and security consequences:

  1. Cookies cannot be tagged as HTTPONLY
  2. Potential XSS vulnerabilities in subdomains can introduce poisoned cookies in upper domains

Cookies that contain sensitive server metadata, such as session cookies, should be tagged as HTTPONLY. This prevents client-side scripts from reading values from the cookie, adding a layer of protection. Given that this pattern requires client-side scripts to read the token from the cookie and apply it to the HTTP header, we cannot tag the cookie as HTTPONLY, introducing a potential security concern.

Leveraging this pattern requires that all software in our suite of applications are fully XSS-resistant. If an application in a subdomain, below our application domain, is compromised within the context of an XSS attack, an attacker could potentially introduce a poisoned cookie to that site, which would be valid in our upper domain, and allow an attacker to circumnavigate our CSRF protection framework.

Conclusion

Both methods of protection introduce design and potential security consequences. As a result, I’ve created a new pattern, the Encrypted Token Pattern, to address these concerns.

Encrypted Token Pattern

This pattern addresses the shortfalls of both the Synchronizer Token Pattern and the Double-Submit Cookie Pattern as follows:

  • It does not require server-state
  • It does not require cookies
  • It does not require two tokens
  • It does not require any effort on the client-side other than including the token in HTTP requests
  • It does not require any other application in a subdomain to be XSS-proof

The Encrypted Token Pattern is described here.

Summary

The Encrypted Token Pattern solves the shortfalls of other CSRF protection patterns and allows us greater control over CSRF-defense, without introducing new security concerns or architectural problems.

Check out this post for a simple walkthrough outlining the steps involved in leveraging ARMOR to protect your application against CSRF attacks.

Connect with me:

RSSGitHubTwitter
LinkedInYouTubeGoogle+