Security Best Practices

From Harmoni

Jump to: navigation, search

The two primary security breaches in web applications are SQL injection and code injection. While Cross-Site-Scripting is also an issue, it will not be addressed in this document. In addition to encouraging code reuse, one of the drivers in the design and development of Harmoni was to create a framework that made it easier to create reasonably secure applications. The Harmoni project has not [to date] had a team of security researchers pouring over every detail of its implementation, though if you are a [or have a team of] security researcher[s], we would love any help auditing the system. That said, we have taken a wide variety measures in the design of the system so that secure applications can be built with it and to increase the chances that a Harmoni-based application will be developed in a secure way.

Contents

SQL injection

One of the primary vulnerabilities in PHP web applications is that of SQL-injection. At the root of all SQL-injection vulnerabilities is improper quoting/escaping of parameters in SQL queries. This data may or may not be directly passed by the user, but may be resident in the database from previous user-additions or come into the system from a third-party data source, such as an LDAP authentication system.

In order to prevent SQL injection, all query parameters that are not SQL keywords or functions must be surrounded by quotes (i.e. 'xxxxx') and have any internal quotes escaped (i.e. 'xxx\'yyy\'xxx'). While this is a straight-forward process, all too often a parameter here or there will not get this treatment, resulting in a vulnerability.

To make the querying process less prone to error (as well as to provide a cross-database wrapper), Harmoni provides its DatabaseManager. The DatabaseManager system includes the manager itself as well as query objects and result objects. The key feature of the DatabaseManager as pertains to security is the availability of methods in the various query objects that provide the necessary quoting and escaping of values. These include the following:

all except insert

  • addWhereEqual( $column, $value )
  • addWhereNotEqual( $column, $value )
  • addWhereLessThan( $column, $value )
  • addWhereGreaterThan( $column, $value )
  • addWhereLessThanOrEqual( $column, $value )
  • addWhereGreaterThanOrEqual( $column, $value )
  • addWhereNull( $column, $value )
  • addWhereNotNull( $column, $value )
  • addWhereIn( $column, $value )

The methods above add a where clause to the where where the columns and values are appropriately escaped, quoted, and/or checked. There are also additional 'Raw' methods that match the ones above to allow the addition of values that are not quoted and escaped to allow the usage of SQL keywords or functions such as NOW().

insert/update

  • addValue( $column, $value )
  • addRawValue( $column, $value )

The methods above allow the specification of column/value pairs in any order desired. In the insert query, the createRow() method can be used to start a new row of values. As with above, the addValue( $column, $value ) method will quote and escape the value while addRawValue will not.

Using the DatabaseManager and methods listed above eases the burden of remembering when and where to quote and escape values. Raw values or arbitrary SQL commands can be added to any query, but by minimizing the number of those needed, the few that are left can be easily audited.

Code Injection

Code injection vulnerabilities are those in which undesired PHP code is executed on the server. There can be a multitude of ways of accomplishing this, but the most common are:

  • uploading a PHP script to the server
  • passing code as a parameter that will be used in an eval(), exec(), or shell_exec() statement
  • tricking the script into including PHP code from an unintended source

uploading a PHP script to the server

If file uploads (such as user images and documents) are to be allowed safely, then one of three things needs to be done:

  1. Store files in a non-web-accessible place either file-system or in a database and retrieve their data with a script
  2. Store files in a web-accessible directory with PHP execution disabled.
  3. Filter file uploads and prevent PHP scripts and other possibly unsafe scripts from being uploaded.
To ease data management and prevent inadvertent web-server configuration issues from accidentally enabling execution of user data, the Harmoni RepositoryManager stores its file data in a database as per item 1.

Injection into eval(), exec(), shell_exec(), include(), and require()

While these statements should always be used carefully, a common vulnerability goes like this: all variables are carefully defined a config, execution of the index.php file includes several scripts, which then include other scripts based on the based on some parameters, such as what theme to use for the current item. The theme variable is defined in the config, but if the initial script (index.php in this example) is bypassed and the theme-loading script is accessed directly with its theme-to-load variable uninitialized, then it may be possible to substitute a new [on or off-site] path of the script to be included the request or a cookie. Having REGISTER_GLOBALS turned on virtually guarantees this problem, through even without REGISTER_GLOBALS, access of scripts out of their intended order can result in vulnerabilities or errors.

One good way to help prevent these sort of vulnerabilities is to provide one and only one entry point to the scripts. Harmoni's 'ActionHandler' system provides a straight forward way route user requests to various scripts while all requests go only to the index.php controller. While the entire harmoni codebase can and will run in a web-accessible directory, providing web-access only to the index.php file and directories of images, CSS, and Javascript files, is much safer. The Segue2 directory structure is provide below as an example of how this may be set up.

  • segue2-web -- web-accessible
    • index.php -- symlink to segue2-code/index.php
    • images/ -- symlink to segue2-code/images/
    • javascript/ -- symlink to segue2-code/javascript/
    • polyphony/
      • images/ -- symlink to segue2-code/polyphony/images/
      • javascript/ -- symlink to segue2-code/polyphony/javascript/
  • segue2-code -- NOT web-accessible
    • config/
      • ...
    • index.php
    • images/
      • ...
    • javascript/
      • ...
    • main/
      • ...
    • themes/
      • ...
    • harmoni/
      • ...
    • polyphony/
      • docs/
        • ...
      • images/
        • ...
      • javascript/
        • ...
      • library/
        • ...
      • modules/
        • ...

As can be seen above, the only PHP script that can be accessed is index.php. All requests must go through that same script and be subjected to any filtering or security checks done there. The images directory contains only system icons, not user-uploaded data.

Personal tools
applications and initiatives