References

advertisement
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).
Download