Jordan 1 Daniel Jordan CPSC 333 Dr. Kenneth Kung 10 December 2014 Web Security in the 21st Century In the early days of the World Wide Web, application security was virtually non-existent. While business tried to figure out what to do with this new and expanding technology, very little was known about the potential security threats. A common security practice in the early 1990s was to simply enforce access control through a hardware firewall. This has been proven time and again to be not enough. While network security was the area of focus for security specialists, attackers quickly began targeting web applications directly, through browser initiated attacks. Twenty years later, and many of these exploits still exists today. This paper will discuss some of the most common attacks currently used today, as well as discuss how to defend against them. Towards the end of the ‘90s, the world began to pay attention to the every growing threat of attacks on the internet. Products such as application firewalls and vulnerability scanners became standard practice with large scale web applications. Conferences were being held to discuss new cutting edge attacks, and how to defend against them. And large organizations dedicated to web security began to form. These organizations sought to educate developers about various security threats, and teach how to defend against such threats. One of the largest of these groups is the Open Web Application Security Project (OWASP). OWASP is a non-profit organization comprised of security experts, corporations, and educational organizations from all around the world. Every couple of years, OWASP publishes a list of the top 10 vulnerabilities to Jordan 2 web applications. This list, known as the OWASP Top 10, has become the definitive ranking of web application security threats. Amongst the top 10 security threats are Injection, Cross-Site Scripting (XSS), Cross-site request forgery (CSRF), broken authentication exploits, exposure of sensitive data, and misconfiguration of server security [1]. While other security threats have come and gone, injection has remained as one of the top threats to web applications since they first began appearing around 1998. While many forms of injection attacks exists, SQL injection is the most commonly used with web applications. With the advent of server-side scripting languages in the mid ‘90s, pages on the internet began transitioning from static webpages into dynamic database-driven applications. Many of these pages relied on some sort of input to produce content. This can be handled internally by the application, or through the use of a text input provided by an untrusted user. For database-driven applications, this input is then relayed to a database in the form of a query string. Many applications include an additional layer between the user and the database, to validate the data entered by the user. Applications that do not provide this form of validation or sanitizing are left Jordan 3 vulnerable to SQL injections. Vulnerable applications take the data from the user, and concatenate a query string to pass to the database. By not sanitizing the user input, an attacker can modify or extend the query string to retrieve additional data from the database. SQL is a query based language, and thus uses conditional statements in search clauses. If an attacker were able to trick a database query into always returning true, then they would be able to manipulate the application to retrieve sensitive data, or gain access to a system. To achieve this, an attacker simply needs to modify the query string being passed to the database. With a little luck, an attacker can guess the structure of the query being used for a particular application, and modify the string. The code below is a common use of a query for a PHP application, to display user account information for a user with a particular username and password. This code will take input posted from an HTML form, and inject it straight into the search query. The database will then return all columns for a row entry with a username and password matching the entered data. If the attacker were able to modify this query string to always return true values for “name” and “password”, then they would have access to the entire “users” table. Using the data entered in the form above, the previous query string would be transformed into the following string: Because 1=1 is always true, this query will return “True AND True” for every row in the users table, thus bypassing any form of authentication for the user. In addition to altering the logic of a query, attackers can also inject their own commands directly into the query, using the same Jordan 4 technique. This is often used to modify the structure of the database. The input provided in the form above is an example of how an attacker would be able to completely remove a table from a database. Like the previous examples, the attacker supplies a username for the WHERE clause of the query, and then adds a single apostrophe and semicolon to complete the SELECT statement. After the semicolon, the attacker is able to chain additional commands together, such as the DROP TABLE command used above. The use of the double hyphen “--“ exploits the built in commenting feature of the SQL syntax. The double hyphens allow an attacker to bypass the rest of the query by commenting it out, ensuring that their input is the final statement executed on the database. This technique is useful in the scenario where one field of the input is properly sanitized, but others are not. This would allow the attacker to exploit vulnerable fields while bypassing the others. In addition to chaining commands, attackers are able to override existing queries with their own. SQL has the ability to union two select queries, as long as the queries have the same number of columns. Once an attacker has determined the number of columns returned by the query, they can override it with their own query. This is done by ensuring the left side of the union (the original query) always returns false. This type of attack is referred to as a Union-Based SQL Injection. The input provided above illustrates how an attacker would be able to execute a union-based injection attack. The provided input would produce the following SQL query: Jordan 5 By beginning the input with a closing apostrophe, the attacker is able to add a conditional statement to ensure the left side of the WHERE clause will always be false. They are then able to union the empty results with their own query, returning a list of tables from the database schema. This same technique could be used to retrieve column names, data types, database users, and information about the server, such as database version and system variables. When defending against SQL injections, there are several steps a developer must take to ensure their application is safe. Most importantly, any input provided by the user must be properly sanitized before it is passed to a query. Sanitizing user input ensures that any characters that could be used to modify a query will be properly escaped, and processed as string input. While some languages natively offer functions to escape text strings, many SQL driver implementations offer a specific function to accomplish this. One of the most commonly used web application stacks in use today is the L.A.M.P stack. L.A.M.P stands for Linux, Apache, MySQL, PHP. As of 2014, it is approximated that as much as 82% of web servers on the internet are running PHP as their server-side language [3]. The MySQL driver for PHP contains the function mysqli_real_escape_string(), which accepts a character string and database connection as parameters. The database connection is used to retrieve the correct character set used by the database. Characters encoded by this function are NUL (ASCII 0), \n, \r, \, ', ", and Control-Z [4]. Returning to a previously used example, mysqli_real_escape_string() would transform the SQL query into the following: In this example, the apostrophe is properly escaped, and the database will simply look for a Jordan 6 username matching the string “testUser\’; DROP TABLE users;--“. In addition to properly sanitizing user input, a commonly overlooked defense is the manual processing of database errors. When an SQL query fails, the database will return a descriptive error detailing the point of failure. Attackers often look for these errors when determining if an application is vulnerable to SQL injection. These errors can reveal information about the structure of the database, as well as the query being used. This approach is referred to as an Error-Based Injection attack. In addition to using these errors to determine their point of attack, an attacker can inject their own queries which will be displayed on the error page. Information such as the database name, table name, table schema, logged in user, and system version can all be retrieved through global variables that can be passed directly into a query. In addition to SQL injection, another popular type of code injection carried out on web applications is PHP injection. Just like SQL injection, PHP injection relies on injecting user input directly into a variable without sanitizing or validating the data. Applications which are especially vulnerable are those that take advantage of the PHP function shell_exec(). This function allows an application to access the shell on a system (Windows and Unix supported), and execute a command. Once completed, the function then returns the contents of the shell session back to the application. The code above takes a parameter passed through the URL, and returns the file contents back to the browser. No additional sanitizing or validation is done to the parameter. As shown in the Jordan 7 image below, passing a single file name to the application will return the contents to the browser. By appending this string with a semicolon, an attacker can pass additional commands to the shell, and essentially gain control of the system. Below is an example of this, with an additional “ls” command added to the file parameter. The application returns the contents of the text file, along with a listing of each file and directory in the given directory. Unix Shell commands are outside of the scope of this paper, but an attacker could use this type of attack to execute a malicious shell script remotely, and take control of the system. Much like SQL injection attacks, the simplest way to defend against a PHP Shell attack is to properly sanitize the user input. Much like the MySQL library for PHP, there is a specific function for escaping PHP shell commands. Using the function escapeshellcmd(), the characters #&;`|*?~<>^()[]{}$\, \x0A and \xFF. ' and " will be properly escaped prior to executing [5]. In addition to sanitizing input to prevent chaining commands, additional security controls are available in the PHP configuration file for each server. In this file, an administrator can choose to disable the shell_exec() function all together, or limit it’s permissions. Jordan 8 References [1] The Open Web Application Security Project (OWASP). Top 10 2013-Top 10 - OWASP Last updated August 26, 2014. Available from https://www.owasp.org/index.php/Top_10_2013Top_10 (accessed December 01, 2014). [2] The Open Web Application Security Project (OWASP). “SQL Injection.” Last updated December 6, 2011. Available from https://www.owasp.org/index.php/SQL_Injection (accessed December 01, 2014). [3] W3Techs. “Usage of Server-side Programming Languages for Websites." Last updated November 7, 2014. Available from http://w3techs.com/technologies/overview/programming_language/all (accessed December 05, 2014). [4] PHP.net. “Mysqli::real_escape_string." Available from http://php.net/manual/en/mysqli.realescape-string.php (accessed December 05, 2014). [5] PHP.net. “escapeshellcmd " Available from http://php.net/manual/en/function.escapeshellcmd.php (accessed December 05, 2014).