Thirty-one-year-old Laurie Love is currently staring down the possibility of 99 years in prison. After being extradited to the US recently, he stands accused of attacking systems belonging to the US government. The attack was allegedly part of the #OpLastResort hack in 2013, which targeted the US Army, the US Federal Reserve, the FBI, NASA, and the Missile Defense Agency in retaliation over the tragic suicide of Aaron Swartz as the hacktivist infamously awaited trial.
Love is accused of participating in the #OpLastResort initiative through SQL injection attacks, an increasingly common tactic. SQL injections have recently been detected against state electoral boards, and these attacks are regularly implicated in thefts of financial info. Today, they’ve become a significant and recurring problem.
SQL injection attacks exist at the opposite end of the complexity spectrum from buffer overflows, the subject of our last in-depth security analysis. Rather than manipulating the low-level details of how processors call functions, SQL injection attacks are generally used against high-level languages like PHP and Java, along with the database libraries that applications in these languages use. Where buffer overflows require all sorts of knowledge about processors and assemblers, SQL injection requires nothing more than fiddling with a URL.
As with buffer overflows, SQL injection flaws have a long history and continue to be widely used in real-world attacks. But unlike buffer overflows, there’s really no excuse for the continued prevalence of SQL injection attacks: the tools to robustly protect against them are widely known. The problem is, many developers just don’t bother to use them.
One of Microsoft’s less valuable innovations
The earliest description of these attacks probably came in 1998, when security researcher Jeff Forristal, writing under the name “rain.forest.puppy,” wrote about various features of Microsoft’s IIS 3 and 4 Web servers in the hacker publication Phrack.
IIS came with several extensions that provided ways to generate webpages based on data from databases. Then and now, most databases use variants of a language called SQL (Structured Query Language) to manipulate their data. Databases using SQL organize data into tables built up of rows and columns. Each table represents a particular kind of thing. Each column of the table represents a particular fact about that thing, and each row of the table is an instance of that thing. So, for example, a table named “people” might have columns for “age” and “name,” with each row in the table representing a specific person. SQL is used for both defining these tables and columns and for manipulating the rows within them.
Sometimes, the SQL query that these IDC and ASP files used for grabbing information from the database was hardcoded; that is, the same query was used every single time the webpage was loaded. But because the query was often written to take one or more parameters, the data shown on that page could change as those parameters changed.
For example, an online store might have a page named
order.asp to display the contents and status of an order. Each order is identified by an order ID, with the order ID passed as a parameter to the page as part of the URL:
order.asp?orderID=1234, say, to view the order with ID 1234. The ASP page would take the parameter from the URL and combine it into an SQL query, which was then sent to the database for lookup.
What Forristal noticed was that the way these parameters were combined to build the query meant that an attacker could force the database to execute other queries of the attacker’s choosing. This act of subverting the application to run queries chosen by an attacker is called SQL injection.
A popular tool to this day
Since their initial discovery, SQL injection flaws have routinely been discovered in the wild and used to compromise vast quantities of data. While Forristal looked at Microsoft’s software first, SQL injection was an industry-wide problem; sites using Java, PHP, ColdFusion, Ruby, and Python have all had SQL injection flaws. Virtually every technology that can be used to build dynamic, database-driven websites is susceptible to SQL injection.
And attacks using SQL injection are abundant. Earlier this year, a Florida man was charged with felony hacking after using SQL injection to read sensitive data from an election site. SQL injection vulnerabilities in the Joomla CMS and popular WordPress plugins have put hundreds of thousands of blogs at risk of attack. Security firm HBGary was devastatingly attacked in 2011 after members of the Anonymous collective discovered SQL injection flaws in a custom-developed content management system. The group responsible for that attack would later go on to call itself Lulzsec.
What makes these attacks particularly valuable to attackers—and devastating to victims—is their dual power to both read sensitive data from a database and to write new or updated data to the database. With this power to inject SQL, attackers could potentially read usernames, passwords, credit card numbers, Social Security numbers, or whatever else happened to be stored in the database.
But they could also add their own data. In a well-designed system, passwords, for example, won’t be stored as plain text but instead will be irreversibly transformed into a hashed value. Merely reading the database therefore won’t be sufficient to let an attacker log in and snoop around; while the database will contain the necessary username, it won’t reveal the password. The ability to write to the database, however, means that an attacker can simply create additional user accounts—ones for which they do know the passwords—and log in with those.
Similarly, if the database is used to store any kind of auditing information, such as tracking logins and other user activity, the ability to write to it means that hackers can clean up after themselves, deleting any record of their attack.
To understand how these attacks happen, we need to understand how Web applications use databases. Basic SQL queries have a fairly simple structure. For example, a call to search for a particular order might look like