5 Common PHP security issues and how to address them

Posted by on Dec 17, 2011 in blog, copywriting | No Comments

PHP has developed into the most popular language for programming on the web, but like all languages, it has its weaknesses. Described below are some of the more common areas of vulnerability found in PHP web applications and suggestions on how they can be managed and prevented.

 

1. SQL injection

What is it?

One of the most common forms of hacking, it is an attack specifically targeted at database-driven web applications or websites which link to and interact with databases. A SQL injection attack is a type of code injection where the attacker exploits vulnerabilities in the website’s security measures in order to send special SQL queries to the database that can modify it, delete data and tables within it or delete the whole database in the worst case.

Attacks occur when the developer has failed to build in any checking or data validation functionality for the areas of the site where data from external sources can be inserted into the site. Attackers will append their own SQL statements into unprotected SQL queries that utilise data submitted by a user to look up something in the database.  Attack entry points can include search boxes, login forms, email query forms, signup boxes, etc.

Where user input is allowed to directly interact with building the SQL statement which interacts with the database, with no form of filtering, an attacker can easily control the statement that is executed.

So for example, an unprotected statement would be:

$query = “SELECT * FROM users WHERE username = ‘niki'”; 

A SQL injection query will result in the following attempt:

$query = “SELECT * FROM users WHERE username = ” or ‘1=1′”;

The result returned here would always be true, and thus the contents of the entire table users would be displayed.

What are the implications?

Attackers can gain access to all the information in the database including names, usernames, passwords and other sensitive information.

Tables and information in the databases can be altered, created or dropped which could obviously have dire effects on the front end of the website.

The entire website can be defaced if the hacker gains admin privileges.

How can it be prevented?

  • Data must be verified, validated and cleaned up before it can enter the application – all input received must be sanitised.
  • Sensitive information such as passwords should be encrypted using SHA or SHA1
  • Any technical information must be removed from error messages which can sometimes contain technical details that might reveal security vulnerabilities to an attacker. Attackers will specifically look to error messages to get information such as database names, table name and usernames. Error messages can be disabled or you can create your own custom error messages.
  • Limit the permissions granted on the database – the fewer permissions, the lower chance of attack – for example, people accessing the front end of a website through a signin need  far fewer permissions than someone accessing the backend CMS.
  • The best way to santise data is to ‘escape’ any characters in a string entered into the website which may have special meaning in MYSQL and therefore potentially be dangerous. When a character is escaped it is effectively ignored by the database and made ineffective in a query. The standard character used by PHP and MY SQL to escape characters is the backslash (). This technique is used in several functions in PHP which exist to protect and sanitise data.

The mysql_real_escape_string  escapes any special characters in a string and replaces characters that have a special meaning in MySQL with an escape sequence for use in an SQL statement  – the function adds backslashes to the following characters – n, r, x00, x1a, ’, ” . Note: this function is for PHP versions 4.3.0 and above. Another (older) option to use is addslashes.

There is a function called magic_quotes_gpc  – when this on, then all the POST, GET, COOKIE data is escaped automatically, but this function is now deprecated.

You can take your protection one step further and prevent words such as ‘update’, ‘insert’, ‘drop’, and ‘union’ from being added to the database (these all being words which can alter tables and databases), but this may affect valid queries on your database.

  • One way to bypass the problem if you are an inexperienced developer is to use a pre-existing framework such as CakePHP (http://cakephp.org/) or a prebuilt CMS such as WordPress or Drupal, which have built-in routines and security measures to prevent SQL injection.

 

2. Cross Site Scripting (XSS)

What is it?

Probably the most common form of hacking, this is where a hacker uses a legitimate website’s vulnerability to force that website to do certain things. The malicious user embeds client side scripting commands (often JavaScript or HTML but can be, VBScript, ActiveX or Flash) in order to collect session information and cookies and use these to hijack sessions and further attack the site. The inserted code can be used in several ways, including to steal other user’s private information or to deface the site by rewriting the content of the HTML pages.

Forums and message boards are especially vulnerable to this type of attack. An example would be: a hacker will create his own malicious website and inject hyperlinks onto the legitimate site – hyperlinks and email links are often posted in forums. When a user clicks the hyperlink, the vulnerability in the legitimate website allows the injection of malicious code into that site, and from there onto the user’s machine via their browser.

What are the implications?

Once injected, the malicious code is stored in the website’s database and when it is fetched and displayed to the visitor, the resultant page can be distorted – code can also be run which steals cookies or sends information such as the session ID to a malicious third-party site.

If JavaScript is injected into the HTML source, it can also be used for simple things such as redirecting a user to a spam website or in a more sophisticated attack such as keylogging  –  sending the user’s keystrokes (e.g. passwords) to an external database.

XSS can be used for user-account hijacking, changing user’s settings and stealing their confidential information. As mentioned, sessions and cookies can be hijacked or stolen, altered and reused. New uses are continuously being found for XSS by hackers, according to Cgisecurity.com.

A method used in conjunction with XSS is known as Cross-Site Request forgery. This is where the malicious code tricks the user’s browser to send requests under the guise of the legitimate user, so for example, it could use a user’s online email account to automatically send out emails such as spam mail.

How can it be prevented?

As with SQL injection, the best way to prevent XSS is to use escape functions. Specifically to escape characters that comprise HTML and JavaScript syntax like ‘<’ and ‘>’ or to convert them into HTML entities, (so < would become &lt; for example).

The htmlspecialchars () function indentifies any output you don’t want to be HTML output and converts it into plain HTML entites, so for example: ‘&’ becomes ‘&amp;’ and ‘”‘ (double quote) becomes ‘&quot;’

The htmlentities() function can also be used and it similarly converts all applicable characters to HTML entities.

In forum websites, where legitimate users will want to post HTML such as links, an alternative syntax such as bbcodes (which is very common on forums) can be used to overcome the escaping of HTML characters.

The most important way prevent XSS is to rigorously test the site before launching it.

 

3. Remote file inclusion and remote code execution

What is it?

This is a security breach which allows an unknown or malicious party to run code on your web server or client side and can lead to several further types of hacking.

Remote file inclusion is caused by a site vulnerability which allows an attacker to deploy a malicious file onto the web server. This can be caused by improper use of the include() and require() functions when the register_globals directive is on(allowing the user to initialise variables remotely). The register_globals directive is the setting which controls the availability of superglobal variables (e.g. form data, cookie data). If the directive is on, an uninitialized variable can be used to include unwanted and malicious files from remote locations. If the allow_url_fopen is enabled in php.ini, remote files can be uploaded to the website’s server via HTTP or FTP from a remote location.

What are the implications?

Remote file inclusions can lead to things such as data theft, remote code execution on the server, code execution on the client-side leading to problems such as cross site scripting and denial of service (DoS).

Remote code execution on the server side means that if the file that the attacker has included is a shell (a file which can affect the operating system) the attacker can run system-level code on the server and use this to retrieve or alter data on that server or hack the end-user’s terminal.

Client side remote code execution can lead to cross site scripting, as discussed in the previous section of this essay.

Denial of Service prevents the users of a site from being able to access that site by preventing the web servers from serving web pages or overloading the server with requests, slowing it down and basically making the site inaccessible.

How can it be prevented?

The register_globals directive should always be OFF – in later versions of PHP, it is off by default, but one should always check that.

If the register_globals directive has to be set to ON for some reason, all variables must be correctly initialised.

There are other php directives can be used to prevent remote file inclusion, which include:

  • allow_url_fopen (set to on by default)  –  controls whether remote files should be includable and should be turned to OFF.
  • allow_url_include (set to off by default)  –  controls whether the include(), include_once(), require() and require_once() commands are able to include remote files into the code.
  • Enabling safe_mode which forces PHP to test of user ID permissions before opening files.

Additional precautions include always validating user input and being very careful with any data retrieved from remote servers or locations. The simplest way to stop it is to just ensure that all include files are locally hosted and to never accept files from anywhere else unless absolutely necessary.

Restricting user privileges to an absolute minimum can also help prevent this.

 

4. Session and cookie hacking

What is it?

The hacking of sessions and cookies cannot breach the database or the web application itself, but can compromise user accounts.

A session is an entity triggered when a user initiates contact with a server and consists of a period of interaction between the user and the web application which may be authenticated using security measures such as a password and username. During this session, the web application will store a file or cookie on the user’s machine (browser) which will contain information about the session such as the user’s preferences, authentication data or for example, shopping cart information.

XSS, discussed previously is the most common way in which hackers can steal cookies. Another risk is when hosting is shared by multiple people and session ID’s are stored in a shared /tmp directory, meaning anyone can access and read them.

 What are the implications?

When a user logs in to a site, a session ID is created for the user, and a session hacker will try to obtain the legitimate user’s session ID and use the information. When the hacker steals and tries to reuse a session ID, it is known as session fixation, and it could basically allow the hacker to login as an authentic user and cause damage or alter the user’s account – this is particularly dangerous when the user is an administrator or someone whose account contains sensitive data.

How can it be prevented?

Session ID’s should be changed often, therefore the session_regenerate_id() function should be used every time the user logs in, assigning them a fresh ID – this prevents hackers from setting session ID’s prior to login.

Risks can be mitigated by revalidating a user who is about to perform sensitive tasks such as resetting their password (i.e. by making them re-enter their old password).  Also, if a password is to be stored in a session variable, it must be encrypted (using the sha1() function), but most sources suggest it is best not to store a password in a session variable at all.

In cases of shared hosting, you can redirect the data to be saved in a location only you can access by using the session.save_path directive.

Using an SSL or secured connection if your web application is handling sensitive information such as credit card numbers can also prevent session and cookie hacking.

 

5. Directory traversal (aka path traversal)

What is it?

This is a method of exploiting web applications by accessing files beyond the document root directory allowing the hacker to view restricted files and folder and interact with the server by executing commands. The attack usually occurs through a web browser and is accomplished by the attacker entering a URL into the address bar which will take him out of the root directory and into the main server directories – this would generally take some guesswork on the part of the hacker, but can actually be pretty easily done. It can also be achieved through input portals on the front end of the web application.

What are the implications?

Once inside the server’s system files and folders, the hacker has access to all sorts of information and sensitive data including application source code, configuration and critical system files. They may even add or delete files and play havoc with the server’s setup.

How can it be prevented?

The simplest answer is that you should sanitise and validate all user input correctly by removing all suspect data and filtering out meta characters.

Another precaution to take is to never store sensitive configuration files inside the web root.

Wikidpedia suggests that if a suspect request to a file is made, the full filepath should be built up, if it exists and all the characters in the path should be normalised (e.g. change %20 to spaces).

In addition, careful programming on the web server is very important as are the use of security software, patches and vulnerability scanners.

 

 

Conclusion

These are but a few of many security vulnerabilities presented by the PHP web application setup – there are many more. But there are certain fundamental things one can do to prevent the bulk of the worst and most damaging attacks.

To recap:

Firstly, all data that comes from outside your web application must be validated, filtered and sanitised – failure to do this leaves you wide open to attacks.

Secondly, all error outputs should be turned off once the application is live, as they can give attackers vital information about the web application such as database and table names. Once live, all errors can be written to a log file instead.

Controls and directives which allow files to be uploaded to your site should all be turned off unless absolutely necessary. These configurations would be set inside the php.ini file. PHP configuration can directly influence the severity of the effects of an attack and are often set to insecure values by default…the recommended settings for maximum security are:

  • register_globals – OFF
  • allow_url_fopen – OFF
  • magic_quotes_gpc –  OFF
  • safe_mode and open_basedir – enabled and correctly configured.

 

Variables should always be initialised as uninitialised variables present a huge security risk.

Development accounts (such as username: admin, password: admin) and default usernames and passwords should always be eradicated before the site goes live.

PHP Frameworks and prebuilt CMS applications are generally very secure and could be considered an option for inexperienced developers.

Consider using security applications and testing software to check the security of your applications – there are many PHP tools to test code security such as PHP Security Scanner, Spike PHP Security Audit Tool and PhpSecInfo.

 

References

Web references:

  1. Breaking down scary terms and what they mean: http://technosailor.com/2010/12/30/infosec-101-breaking-down-scary-terms-and-what-they-mean/
  2. Chapter 11:  Shell commands:  http://omake.metaprl.org/manual/omake-shell.html
  3. Common PHP Security Mistakes and What You Can Do About Them: http://www.eweek.com/c/a/Security/Common-PHP-Security-Mistakes-and-What-You-Can-Do-About-Them-427112/
  4. Directory Traversal Attacks:   http://www.acunetix.com/websitesecurity/directory-traversal.htm
  5. Five common Web application vulnerabilities by Sumit Siddharth, Pratiksha Doshi : http://www.symantec.com/connect/articles/five-common-web-application-vulnerabilities
  6. How to Fix PHP Vulnerabilities (So Your Site Won’t Get Hacked): http://www.codediesel.com/php/how-to-fix-php-vulnerabilities/
  7. HTTP cookie: http://en.wikipedia.org/wiki/HTTP_cookie
  8. Introduction To PHP Security Vulnerabilities: http://debuggable.com/posts/introduction-to-php-security-vulnerabilities:480f4dfe-97f8-4975-ab28-4eb0cbdd56cb
  9. mysql-real-escape-string : http://www.php.net/manual/en/function.mysql-real-escape-string.php
  10. Path Traversal: https://www.owasp.org/index.php/Path_Traversal
  11. PHP dig: http://www.phpdig.net/ref/rn41re781.html
  12.  PHP Top 5:  https://www.owasp.org/index.php/PHP_Top_5
  13. PHP Security: http://en.wikipedia.org/wiki/PHP#Security
  14. Rfi (remote File Inclusion) What Is It? How Do I Stop It?: http://www.knowledgesutra.com/forums/topic/61805-rfi-remote-file-inclusion-what-is-it-how-do-i-stop-it/
  15. The Cross-Site Scripting (XSS) FAQ: http://www.cgisecurity.com/xss-faq.html
  16. Threat glossary: http://www.h-spot.net/threat_glossary.htm
  17. Top 7 PHP Security Blunders: http://www.sitepoint.com/php-security-blunders/