October 13, 2015

Handling Software Vulnerabilities, Part I

Software security is becoming increasingly important due to the numerous emerging threats exploiting software vulnerabilities. Most software systems today contain design and implementation bugs that can be exploited by attackers.

As more development shifts to the web, and more data is stored on the cloud, security is a critically important topic. A single security misstep can compromise confidential business data or your customer’s personal information.

Software security is a lengthy topic, so this blog has been divided into 3 parts. We’ll be covering the following vulnerabilities and their suggested fixes:

  • Injection
  • Cross-site scripting
  • Cross-site request forgery
  • Unvalidated redirects and forwards
  • Common security misconfiguration

So what is software vulnerability?

Software vulnerability is a weakness in the security of a program, often due to a design decision mistake or an implementation mistake.

How does vulnerability affect the security of software?

An exploit is an action (or a piece of software that takes an action) that takes advantage of a vulnerability and results in an attacker making the system perform in ways that are not intentionally authorized (e.g. changes to databases, denial of service or arbitrary code execution). Here are some famous stories about how software vulnerability resulted in an attack:

  • 2011: Oracle’s MySQL.com hacked via SQL Injection Attack
  • 2011: Expedia’s TripAdvisor member data stolen in possible SQL Injection Attack
  • 2012: A security flaw in Google Wallet that leads into full access to your Google Wallet account without rooting or an extra app

The security of a web-based application is a major concern for all developers. Even when developers are trying to do the right thing, it is easy for a mistake to result in an attacker being able to take control of software. Taking the time to secure your application development may involve nothing more than getting to know these common software vulnerabilities and their fixes.

#1 Injection

Injection is responsible for a very large portion of public disclosure and security breaches. There are many types of injection vulnerabilities, most commonly including:

  • SQL injection
  • Command injection
  • LDAP injection
  • XML injection
  • XPath injection

With the different types of injections, the attacker will construct their attack in a different way. Injection vulnerabilities present some of the most significant risks when effectively exploited. Some of these risks can involve:

  • Data loss or corruption
  • Unauthorized access
  • Denial of access
  • Complete host system takeover

The consequences of any of these risks can seriously impact the ability of a software system to function properly.

Let’s see what an SQL injection is and how to fix it.

SQL injections occurs when an input from a user is directly used to construct a dynamic SQL query that is executed by the software. Below is the example of a SQL injection prone code in C#:

public bool Login(string username, string password)
            SqlConnection dbConn = new SqlConnection(connectionString);
            SqlCommand cmd = dbConn.CreateCommand();
            cmd.CommandText = "SELECT UserId FROM UserDetails WHERE username = '" + username + "' AND Password = '" + password + "'";
            cmd.CommandType = CommandType.Text;
            return Convert.ToBoolean(cmd.ExecuteNonQuery());

In the code snippet above, if an attacker enters a string “SampleUsername” and “password’ OR ‘a’=’a” as the username and password parameters, then the resultant query would look like this:

FROM UserDetails
WHERE username = 'username' AND Password = 'mypassword' OR 'a'='a'

The above query will cause the “where” condition to always evaluate as “true,” which allows an attacker to login in to the system without knowing the correct password.

In another example, attackers can paste the following command in the parameter and drop the complete table itself.

mypassword';DROP TABLE UserDetails;--

Avoiding SQL injection is simple. Developers need to either:

  1. Stop writing dynamic queries and/or
  2. Prevent user-supplied input, which contains malicious SQL that can affect the logic of the executed query

Below is the preferred way of writing a dynamic SQL query using “SqlCommand” parameters:

  public bool Login(string username, string password)
            SqlConnection dbConn = new SqlConnection(connectionString);
            SqlCommand cmd = dbConn.CreateCommand();
            cmd.CommandText = "SELECT UserId FROM UserDetails WHERE username = @username AND Password = @password";
            cmd.Parameters.Add(new SqlParameter("@username", SqlDbType.VarChar, 100)).Value = username;
            cmd.Parameters.Add(new SqlParameter("@password", SqlDbType.VarChar, 20)).Value = password;
            cmd.CommandType = CommandType.Text;
            return Convert.ToBoolean(cmd.ExecuteNonQuery());

One thing to keep in mind is that stored procedures are also prone to SQL injection if the SQL queries are executed as a string concatenated with user-supplied data.

More information on SQL injection can be obtained here.

Another critical type of injection is known as XPath Injection. XPath is a standard language used to query the parts of an XML document. Similar to SQL queries, the XPath queries are also prone to an injection attack when a user-supplied value is used to construct an XPath query. This vulnerability may result in enabling an attacker in achieving information disclosure or privilege escalation. Since most of the modern web services are exchanging data in an XML format, the XPath injection may impact your web service severely.

Consider the following XPath query, which validates the supplied user credentials against the values available in an XML document:

XPathExpression expr = navigator.Compile(“//users/user[@name='" + name + "' and @password='" + password + "']");

Similar to a SQL injection attack, an attacker may supply a username of “administrator” and a password value as “xyz’ or ‘a’=’a”. This input will cause a bypass to password check because the “where” condition will always evaluate to true. Fixing an XPath injection is not as easy as a SQL injection because XPath doesn’t support parameterized queries. Therefore, it becomes the programmer’s responsibility to sanitize the user-supplied values by implementing strict input validation or by not accepting values supplied by a user at all.

You can find more information on XPath injection here and here.

This concludes the first part of this multipart blog series on software vulnerability. In the next part, we will discuss cross-site scripting (XSS) attacks and cross-site request forgery (CSRF).