PHP has allowed people with all sorts of backgrounds to put their ideas on the web. With several hundred million webpages programmed in PHP, security plays a big deal for us webprogrammers. In this introduction I will outline the most common security vulnerabilities in PHP scripts. Tutorials on how one can prevent them will be dealt with in articles dedicated to each vulnerability.
All Input is Tainted
As a programming language, PHP generates output (HTML, Headers, Files and the like) based on User Input supplied by the url, cookies, the session data, forms, file uploads.
It is an absolute must that you regard every input supplied by a user as potentially unrelieable. When you operate on user-provided input, you have to validate it before you use it in your system.
By the time input reaches PHP, it's passed through the user's browser, any number of proxy servers and firewalls, filtering tools on your server and possibly other processing modules.
Any of those have an opportunity to corrupt your input - be it intentional or not. As the input ultimately comes from your user, it could have been corrupted in pure malice to push the limits of your application or undeliberately.
There is no universal solution that validates all input. We will learn about the most common ones in a later article where we examine all security vulnerabilities explained here in detail.
Cross-Site Scripting
Cross-Site Scripting (XSS) is one of the most common vulnerabilities of web applications. In such an attack the hacker stores unwanted code, be it Javascript, CSS or HTML, in the victim's database.
Later, when the content is fetched from the database and displayed to the visitor, it alters the page or runs some code that either distorts the overall layout, exploits and steals user's cookies or redirects confidential information like the session id to third-party sites and software.
XSS is very popular and easy-to-do. It only requires basic knowledge of javascript and / or HTML and CSS. There are two forms of XSS exploits: direct action and stored action. The former gains insight about the application whereas the latter, the more dangerous one, tries to steal identities for subsequent exploits towards site users or the site itself.
The simplest XSS attack would be inserting a <blink> tag into a form which has no html tag validation. It could make the entire website to blink awkwardly. :)
SQL Injection
SQL Injection is also a very popular vulnerability that is caused by inconsequent input validation. Unlike XSS Sql Injection is directed at the site itself and can be extremely dangerous, resulting in your entire database being deleted.
The goal of SQL Injection is the insertion of arbitrary data into a string of which the hacker knows that is going to be used in an SQL statement - for example the username of a login form. The malicious query may retrieve
data that otherwise requires authentication, modify or even remove data from the database.
Example
Suppose you have such a login form with a name and a password input field. Now when the form is sent via POST, think about what the following code does:
mysql_query("SELECT * FROM users WHERE name='{$_POST['name']}'");
At first glance it looks okay. However, when the hacker puts "john'; DELETE FROM users;'true" into the name field, the following Query will be executed:
[sql]
SELECT * FROM users WHERE name='john'; DELETE FROM users;'true'
[/sql]
The execution of this query causes all users to be deleted. Now using MySQL's query stacking option will prevent the system from executing multiple sql queries at one mysql_query() call. However, other database systems like PostgreSQL might not.
Code Injection
Code Injection can be the most dangerous attack that can affect a PHP script. This attack is also caused by a lack of input validation.
The core of this attack method is most often PHP's register_globals ini setting, which allows to register variables supplied by $_POST, $_GET and the like as direct PHP variables. Most servers turn register_globals off
by default, which is good. However, some still keep it on.
If a script loads an external script based on user input (that is not validated), an attacker can hijack the site's infrastructure by supplying an arbitrary local or remote filename.
If register_globals is on, this may cause code to be injected into the site, which modifies the database, explores data, scripts and files or compromises the entire system.
Take every possible opportunity to eliminate this vulnerability. In a subsequent article I will show you how it is done.
Command Injection
Command Injection exploits PHP's dependency on external resources. For example for some task the myriad of php functions and extensions is not enough and you depend on a local windows or linux command.
The external command-line utility doc2pdf is commonly used to convert uploaded Word-documents into pdf files. The name of the uploaded file in the following script is not validated and thus may contain all sorts of funny characters:
$dest =
basename($_FILES['uploaded']['name'],
'.doc');
shell_exec("doc2pdf {$_FILES['upload']['tmp_name']} {$dest].pdf");
One of such funny characters are semicolons which separate commands on the command line. If the filename was "somefile; locate * |rm -rf" the shell converts somefile and then removes all files writeable by the web server.
We will see in a later article how you can avoid such an attack.
Session And Cookie Security
Sessions are very helpful to track a user. Sessions maintain an online identity. Therefore, it's disastrous if people steal that identity, performing all sorts of actions that only the original identity had priviledges to perform.
As PHP heads more and more into Enterprise Applications where sensitive data is present, session security is absolutely essential. By exploring how sessions work you can forsee possible attacks. We will see in a dedicated article how this is done and how securing Cookies is done.
Securing File Access
All PHP scripts depend on other files in one form or the other. No matter the size of your application it is vital to maintain the proper access restrictions. Failing to protect files can make it very easy for hackers to compromise the entire system.
In most cases the PHP interpreter has the same user ID as the webserver. Files uploaded by scripts are owned by the developer's user account. Due to differing users, it's not possible to set secure file permissions (0600 for files and 0700 for directories), since the permissions
would prevent the server from being bale to access those files. Do we have to make these files world-readable? We will see in a later article.
Conclusion
These are the most common PHP vulnerabilities., shortly outlined in a compact article. I will write dedicated articles about each of those later where you learn how to prevent them. Those articles will be packed
with many code examples, I am sure many of you have not seen yet. Stay tuned!