Fatal Injection: The Server’s Side.

In my first blog post  I discussed about software security and mentioned some common traps into which programmers regularly fall. One of them involved input validation. For instance, a developer may assume that the user will enter only numeric characters as input, or that the input will never exceed a certain length. Such assumptions can lead to the processing of invalid data that an attacker can introduce into a program and cause it to execute malicious code. This class of exploits is known as code injection attacks and it is currently topping the lists of the various security bulletin providers. Code injection attacks are one of the most damaging class of attacks since they can occur in different layers, like databases, native code, applications and others; and they span a wide range of security and privacy issues, like viewing sensitive information, modification of sensitive data, or even stopping the execution of the entire application.

The set of code injection attacks that involves the insertion of binary code in a target application to alter its execution flow and execute inserted compiled code can be described as binary code injection attacks. This category includes the infamous buffer-overflow attacks. Such attacks are possible when the bounds of memory areas are not checked, and access beyond these bounds is possible by the program. Consider the following code segment:

#include <string.h>

void vulnerable_method (char *foo)
  char tmp[12];
  strcpy(tmp, foo);

int main (int argc, char **argv)

This code takes an argument and copies it to the tmp variable. But what happens when an argument is larger that 11 characters? By taking advantage of this, malicious users can inject additional data overwriting the existing data of adjacent memory. From there they can take control over a program or even take control of the entire host machine. C and C++ are vulnerable to this kind of attacks since typical implementations lack a protection scheme against overwriting data in any part of the memory. In comparison, Java guards against such attacks by preventing access beyond array bounds, throwing a runtime exception. To combat a buffer-overflow attack in the above case you could use strncpy instead (strlcpy is even better if you are running on BSD or Solaris) since it requires putting a length as a parameter.

Code injection also includes the use of source code, either of Domain-Specific Languages (DSLs) or Dynamic Languages. DSL-driven injection attacks constitute an important subset of code injection, as DSL languages like SQL and XML play a significant role in the development of applications. For instance, many applications have interfaces where a user enters input to interact with the underlying relational database management system of the application. This input can become part of an SQL statement and executed on the target RDBMS. A code injection attack that exploits the vulnerabilities of these interfaces is called an SQL injection attack. One of the most common forms of such an exploit involves taking advantage of incorrectly filtered quotation  characters. For instance, in a login page, users wanting to access a vulnerable application have to fill-in a simple username and password form. The following Java code illustrates the defect by accepting user input without performing any input validation:

Connection conn = DriverManager.getConnection(a_url, "a_username", "a_password");
String sql = "select * from user where username='" + uname +"' and password='" + pass + "'";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
if (rs.next()) {
  loggedIn = true;
  out.println("Logged in");
} else {
  out.println("Credentials not recognized");

By using the string anything’ OR ’x’=’x as a username, a malicious user could log in to the site without supplying a password, since the ‘OR’ expression is always true. To avoid a situation like the above, you could use Java’s prepared statements. In a prepared statement, the query is precompiled on the driver that is used to connect the application with the database. From that point on, the parameters are sent to the driver as literal values and not as executable portions of SQL; hence no SQL can be injected using a parameter. ΧPath and LDAP injection attacks are DSL-driven attacks that have a very similar style to SQL injection. Also, notice that contrary to binary code injection, a DSL-driven injection attack is independent of the language that was used to create the application. So the problem above could similarly occur in PHP, C++ etc.

As you have probably realized, the aforementioned attacks target vulnerable, server-side applications. In one of my upcoming posts, we will have the opportunity to discuss about injection attacks that involve dynamic languages and target entities that exist on the client-side (i.e. the user’s browser).