Monthly Archive for April, 2013

PHP Adapter Pattern for Defense against Injection Attacks

injectionAttcksProtect Yourself

Some people (I cannot bring myself to call them ‘programmers’) amuse themselves by conducting injection attacks. Even in a PHP/MySQL site with no value other than its own informative functionality, they get their kicks by screwing with it. I sort of knew about them, but since I’m not particularly interested in security issues, I didn’t pay much attention. However, when writing Learning PHP Design Patterns, Robin Nixon (author of Learning PHP, MySQL, JavaScript, and CSS, 2nd Edition) pointed out that when passing data from HTML to PHP using the $_POST or $_GET superglobal variables, the program was subject to an injection attack. Robin then provided some tips on avoiding them by using mysqli::real_escape_string. I took Robin’s advice, and it is reflected in Chapter 11 use of the Proxy design pattern. (Let me note that I’ve read numerous articles on injection attacks since the publication of Learning PHP Design Patterns, and I am aware that there are several different approaches to preventing injection attacks. As far as this post goes, an Adapter can be used to insert any kind of protection against injection attacks; so if you have another technique you prefer; go ahead and use it in the Adapter.)

A General Defense Pattern?

Recently, I’ve been thinking about using a design pattern as a general way of escaping data passed from HTML. The Proxy pattern is fine, but I tend to use it for login security (even though it has other uses). Also, I was thinking that a design pattern that could be used as a “patch” to an older application to make it “injection attack proof” would be an interesting and useful pattern. For this task, the Adapter pattern immediately came to mind. It could be used to change the passing of data from HTML to PHP and prevent injection attacks. (See Chapter 7 for a full discussion of the Adapter pattern—using both inheritance and composition.) Since this example has quite a bit of code, you might want to download all the files before getting started:
Download

The Defenseless Data Entry Module

Let’s start with a typical OOP setup for a PHP data entry module. We’ll start with the code for the HTML, its CSS and the table for entering the data. It’s all pretty standard, but you need it to proceed. (You will need to click on the View Code button in the following listings to see the code.) The two connection classes (in the download) are described in detail in another post on this blog.

?View Code HTML
 
//HTML
< !doctype html>




Data Entry
 

Send Information

  Name Please
  Email address
  Web Site address (URL)
//inject.css
@charset "UTF-8";
/* CSS Document */
/* 292929,5B7876,8F9E8B,F2E6B6,412A22 */
 
body
{
        background-color:#f2e6b6;
        color:#292929;
        font-family:Verdana, Geneva, sans-serif;
}
 
h1
{
        background-color:#8F9E8A;
        color:#412A21;
        text-align:center;
        font-family:"Arial Black", Gadget, sans-serif;
}
< ?php
//ini_set("display_errors","1");
//ERROR_REPORTING( E_ALL | E_STRICT );
include_once("UniversalConnect.php");
class CreateTable
{
        private $tableMaster;
        private $hookup;
 
        public function __construct()
        {
                $this->tableMaster="injectAdapt";
                $this->hookup=UniversalConnect::doConnect();
 
                $drop = "DROP TABLE IF EXISTS $this->tableMaster";
 
                if($this->hookup->query($drop) === true)
                {
                        printf("Old table %s has been dropped.
"
,$this->tableMaster); }   $sql = "CREATE TABLE $this->tableMaster ( id SERIAL, cusname NVARCHAR(25), cusemail NVARCHAR(40), cusurl NVARCHAR(40), PRIMARY KEY (id))";   if($this->hookup->query($sql) === true) { printf("Table $this->tableMaster has been created successfully.
"
); } $this->hookup->close(); } } $worker=new CreateTable(); ?>

Once all the preliminaries are finished, the following interface and class are simple ones to deal with data entry in a MySQL environment. It is ripe for an injection attack!

< ?php
//Client.php -- this client is only used with the PlainDataEntry
//object. A different Client object is used with the
//Adapter pattern
function __autoload($class_name) 
{
    include $class_name . '.php';
}
class Client
{
   private $plain;
 
   public function __construct()
   {
      $this->plain=new PlainDataEntry(); 
   }
}
$worker=new Client();
?>
 
< ?php
//IDataEntry.php
interface IDataEntry
{
    function getData();
    function insertData();
}
?>
 
< ?php
//PlainDataEntry.php
class PlainDataEntry implements IDataEntry
{
    private $cusname;
    private $cusemail;
    private $cusurl;
    private $sql;
    private $tableMaster;
    private $hookup;
 
    public function __construct()
    {
        $this->tableMaster="injectAdapt";
        $this->hookup=UniversalConnect::doConnect();
    }
 
    function getData()
    {
        $this->cusname = $_POST['cusName'];
        $this->cusemail = $_POST['cusEmail'];
        $this->cusurl = $_POST['cusUrl'];
    }
 
    function insertData()
    {
        $this->sql="INSERT INTO $this->tableMaster (cusname,cusemail,cusurl)VALUES ('$this->cusname','$this->cusemail', '$this->cusurl')";
        $this->hookup->query($this->sql);
        if ($result = $this->hookup->query($this->sql))
        {
            printf("Customer: %s email %s and URL: %s 
have been inserted into %s."
,$this->cusname,$this->cusemail,$this->cusurl,$this->tableMaster); } else { printf("Here's what went wrong: %s\n", $this->hookup->error); } $this->hookup->close(); } } ?>

The call to the Client class from the HTML data entry module is a simple one that instantiates an instance of the PlainDataEntry class. At this stage, think of the Client as little more than a trigger script. Figure 1 shows this simple OOP arrangement:

Figure 1: Class implements interface

Figure 1: Class implements interface

The Client is an integral part of the Adapter pattern; especially when using composition. Figure 2 shows the role of the Client object in relation to the other objects in the Adapter. (The top diagram is generic and the bottom one is what has been implemented for this example.) Note that the identical interface is used as the one shown in Figure 1. This is important because one of the key features of the Adapter pattern is that incompatible interfaces can be used in composition. Specifically, the adapter participant of the design allows incompatible interfaces to work together in a composition. (Keep in mind that this blog focuses on PHP design patterns and getting incompatible interfaces working together is the focal point, and the issue of preventing injection attacks is an illustration of how the Adapter might be used.)

Figure 2: Generic and applied composition Adapter class diagrams

Figure 2: Generic and applied composition Adapter class diagrams

The main participant in all of this is the CleanupAdapter class, and so that is where we’ll start.
Continue reading ‘PHP Adapter Pattern for Defense against Injection Attacks’

Static Connection Objects: Classes, Properties and Methods

connectReusable Connection Tools

Some years ago, Steve Krug wrote a book entitled, Don’t Make Me Think!. That sums up how I feel about MySQL connections with PHP. When I make a PHP-MySQL application, all I want to do is to call up a connection object and method, make my connection and go about using it as a mysqli object. I don’t want to have to think about it. I don’t want to have to re-write an error-handling sequence, and if I change the connection information, I want a single source where I can go and make changes without fear that the whole thing won’t blow sky-high. If you like, you can download the connection files along with a test class before continuing:
Download

The Big Boom Theory

A while back on this blog I posted a simple connection pattern. An interface stored connection information in the form of constants and an implemented class returned a connection object. The idea is to provide a simple and reusable application for MySQL connections.

In the book, I created a similar set of classes for making connections, but instead of using non-static variables I used static ones. The UniversalConnect class shows the use of static variables:


include_once('IConnectInfo.php');
class UniversalConnect implements IConnectInfo
{
        private static $server=IConnectInfo::HOST;
        private static $currentDB= IConnectInfo::DBNAME;
        private static $user= IConnectInfo::UNAME;
        private static $pass= IConnectInfo::PW;
        private static $hookup;
 
        public function doConnect()
        {
                self::$hookup=mysqli_connect(self::$server, self::$user, self::$pass, self::$currentDB);
                if(self::$hookup)
                {
                        echo "Successful connection to MySQL:
"
; } elseif (mysqli_connect_error(self::$hookup)) { echo('Here is why it failed: ' . mysqli_connect_error()); } return self::$hookup; } } ?>

To create an instance of the mysqli object in a static environment, the following line (13) is employed:

13 $this->hookup=UniversalConnect::doConnect();

The property, $this->hookup is a private one in the constructer function of the using class. In tests on two of three hosts, the results showed the following:

Successful connection to MySQL:
Old table proxyLog has been dropped.
Table proxyLog has been created successfully.

However, in the third host, using PHP 5.4, the same code generated the following error:

Strict Standards: Non-static method UniversalConnect::doConnect() should not be called statically, assuming $this from incompatible context in D:\ABC\XYZ\jblow\PHPdp\tablework\CreateTable.php on line 13 Successful connection to MySQL:
Old table proxyLog has been dropped.
Table proxyLog has been created successfully.

Testing it on a fourth server, I got the expected results. But I still could not find what the problem was.

Static for All

The problem turned out to be minor (don’t they always) and was solved simply by making the method that returns the msqli connection static. This required both the doConnect method to be declared static in the interface and in the UniversalConnect class. The following listing shows how the repair was made so that on hosting services with Strict Standards, you won’t run into problems. (It’s also a better overall practice.)


//Filename: IConnectInfo.php
//Substitute your connect info
interface IConnectInfo
{
        const HOST ="localhost";
        const UNAME ="phpDesign";
        const PW ="phpPatterns";
        const DBNAME = "phpBase";
 
        public static function doConnect();
}
?>
 

//Filename: UniversalConnect.php
//ini_set("display_errors","1");
//ERROR_REPORTING(E_ALL);
include_once('IConnectInfo.php');
 
class UniversalConnect implements IConnectInfo
{
        private static $server=IConnectInfo::HOST;
        private static $currentDB= IConnectInfo::DBNAME;
        private static $user= IConnectInfo::UNAME;
        private static $pass= IConnectInfo::PW;
        private static $hookup;
 
        public static function doConnect()
        {
                self::$hookup=mysqli_connect(self::$server, self::$user, self::$pass, self::$currentDB);
                if(self::$hookup)
                {
                        echo "Successful connection to MySQL:
"
; } elseif (mysqli_connect_error(self::$hookup)) { echo('Here is why it failed: ' . mysqli_connect_error()); } return self::$hookup; } } ?>   //The following file is an example of how to use a static method //without instantiating the class of which the method is a part //Any file where you need a MySQL connection works the same. //ini_set("display_errors","1"); //ERROR_REPORTING(E_ALL); include_once('UniversalConnect.php'); class CreateTable { private $tableMaster; private $hookup;   public function __construct() { $this->tableMaster="sandTable";   //Single line to create mysqli object $this->hookup=UniversalConnect::doConnect();   $drop = "DROP TABLE IF EXISTS $this->tableMaster";   if($this->hookup->query($drop) === true) { printf("Old table %s has been dropped.
"
,$this->tableMaster); }   $sql = "CREATE TABLE $this->tableMaster (id SERIAL, uname NVARCHAR(15), pw NVARCHAR(10), PRIMARY KEY (id))";   if($this->hookup->query($sql) === true) { printf("Table $this->tableMaster has been created successfully.
"
); } $this->hookup->close(); } } $worker=new CreateTable(); ?>

The first two files are the interface and implementation for the UniversalConnect object, and the third file is just a sample of what you might use it for.

Keep Host Aware

I’ve had to work with a lot of different hosting services and configurations over which I have little or no control. Currently, I regularly use five different hosts, four of which are run by sysadmins who have levels of skill varying from novice to the-best-there-is (student sysadmins often change our PHP.ini files in the learning process.) The only host I can really control all the time is my host on my LAN. I can change the php.ini file so that I have the desired level of security, standards and access. Because of these variations I often use the following two lines:

ini_set("display_errors","1");
ERROR_REPORTING(E_ALL);

In this way, I don’t have to worry about the skill level of the sysadmin (and I do have to worry!). If I find something I do or don’t like about the php.ini configuration, I can always reset them myself or ask the sysadmin at a later date to make the fix. In the meantime, though, until I’m sure about how the php.ini file is configured, I’m going to include lines that make sure I get full error reporting.

After my experience with the static properties and method, I’m changing my error reporting to:

ERROR_REPORTING( E_ALL | E_STRICT );

In working with design patterns and OOP, you need all the feedback you can get. Of course, the best plan is to set your php.ini file so you have your error reporting set the way you want, but if you don’t have full control over configurations, you need a backup plan.