Attack Surface Reduction

Like input validation, attack surface reduction is both an effective defense against the known attacks of today, and a hedge against any new attacks that you might face tomorrow—attacks that might not even exist in today’s world. Again, if you do nothing else in terms of secure development practices, as long as you thoroughly and correctly validate all your application input and reduce your application’s attack surface as much as possible, you should be able to sleep soundly at night. But before we get too far into principles of attack surface reduction, maybe we’d better explain what attack surface is.

Put simply, the attack surface of your application is all of its code and functionality that can be accessed by any untrusted user. And since we’ve already established that you can never trust a user (with the possible exception of administrators, but even that point is open to debate in some circles), a still simpler definition of attack surface is that attack surface is all of the features of your application. Every time you add a new feature to your application, at the same time you’re adding a potential point of failure and a potential means for an attacker to compromise your system.

Let’s look at a real-world example of this principle: my car. I readily admit that I’m an electronics junkie. Any time a new piece of home theater gadgetry comes out, I have to have it. As soon as the latest iPhones and iPads come out, I have to have them. And the same goes for my cars; whenever I buy a new car, I load it up with every possible electronic gadget option they offer. My latest car has a backup camera, a DVD player, high-definition radio, and an integrated 80GB hard drive for storing music. But of all its cool features, my favorite has to be the GPS.

You just can’t beat the convenience of a GPS. I never have to worry about getting lost, running out of gas, or even getting stuck in traffic. But this convenience comes at a cost of a higher “attack surface” for the car. Since the GPS system retains a memory of where you’ve driven to, anyone who has access to your car can see where you’ve been. This means my wife Amy can tell if I’ve been making a few too many stops at our local Best Buy to “test drive” the new 3D plasma TVs. Worse, if a thief steals my car, he can use the GPS to find out where I live, then come rob my house too. (He can even let himself in with the automatic garage door opener.)

This same principle holds true for software. Whenever you add a new feature to your application, you’re adding a potential point of vulnerability. When Microsoft first released Windows 2000, they installed the Internet Information Server (IIS) web server by default along with the operating system. For any user who wanted a web server, this was a nice bonus, and saved them the time of having to download and install it separately. But for the majority of users—most of whom probably didn’t even know what a web server was, much less needed to have one installed on their machine—it only added an extra way for attackers to get into their system. When attackers found a vulnerability in the IIS hit-highlighting feature that allowed them to bypass authentication mechanisms and access private files on the IIS server, millions of users were affected needlessly.

While you could solve this kind of problem by pulling out all the non-critical features of your application and just developing a bare-bones product, that wouldn’t be a great solution. Features sell products. Users love “bells and whistles”—these are the kinds of things that get them excited about using your application. Consider a map web application like Bing Maps or Google Maps: would you like these applications better if they didn’t offer driving directions, or traffic alerts, or links to local restaurants? No, these features add a lot of value to the application and they’d be missed if they weren’t there. Speaking personally, I’m not going to give up my GPS any time soon, extra attack surface or not.

A better solution to lowering attack surface is to allow the user to opt in to activating certain features rather than installing them by default. This is exactly the strategy that Microsoft took to solve the IIS issue. IIS is still included with every version of Windows, but it’s not installed by default. It’s still incredibly easy to activate—you just open up a control panel and check a checkbox—but if you don’t need it or want it, then you don’t have to have that extra point of potential vulnerability.

Another good example of this (and a more web application–focused example) is the way that Amazon.com handles one-click ordering. Amazon.com has a feature they call “1-Click” that lets users define default billing and shipping options so that they can purchase an item from the Amazon web site literally with a single mouse click. This does make it a lot easier to order goods, especially on mobile devices with limited bandwidth, but it also increases the odds that you’ll accidentally buy something you didn’t mean to. While 1-Click is enabled by default, you can choose to disable it by editing your account settings.

Attack Surface Reduction Rules of Thumb

Since attack surface reduction is really more of an art than a science, it’s difficult to make concrete recommendations as to how to effectively reduce the attack surface of your applications. However, there are some rules of thumb that you can apply that will help you in most situations.

The first attack surface reduction principle you should apply is the principle of least privilege. The principle of least privilege states that you should only provide a user with the permissions that allow him to accomplish what he needs to do, and no more. For example, while an administrator on your web application might require write-level access to the application’s product catalog database in order to add new items or change prices, a standard non-administrative user certainly does not require this access and shouldn’t have it. You can (and should) enforce this at the application level by performing appropriate authorization checks. However, you could reduce your attack surface even more by using different database access accounts for each type of user and locking those accounts down accordingly. This way, even if someone accidentally missed an authorization check (or if an attacker found a way to bypass the checks), the underlying account would still lack any privileges to write to the product catalog and the damage would be minimized.

The best part about this approach is that it doesn’t impact legitimate users at all. Reducing attack surface by disabling features is effective, but it can cause at least a little irritation for those users who really did need or want them. But removing privileges to unnecessary capabilities is a pure win-win: legitimate users never know the difference and it makes an attacker’s job much more difficult.

Another rule of thumb along this same line is that you should not only strive to minimize the permissions that you grant your users, but also strive to minimize the capabilities of the programming calls and objects that you yourself use when you’re writing the application. A good example of this is the .NET object System.Data.DataSet, which is used to keep an in-memory cache of data, usually data that’s been retrieved from a database. DataSet is a flexible, powerful object for working with data—but for many applications’ purposes, it may actually be a little too flexible and powerful. DataSet objects can hold the results from not just a single database query, but multiple queries spanning multiple tables. If you’re a .NET programmer and you have queries that you intend to only pull data from a single table, you should probably use DataTable instead of DataSet. As their name implies, DataTable objects are constrained to a single table of data and consequently have a much lower attack surface.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset