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.

 
//HTML
<!doctype html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="inject.css">
<meta charset="UTF-8">
<title>Data Entry</title>
</head> 
<body>
<h1>Send Information</h1>
<form action="Client.php" method="post">
  <input type="text" name="cusName">
  &nbsp; Name Please <br />
  <input type="text" name="cusEmail">
  &nbsp; Email address <br />
  <input type="text" name="cusUrl" value="http://">
  &nbsp; Web Site address (URL) <br />
  <input type="submit" value="Enter Data into Database">
</form>
</body>
</html>
//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.<br/>",$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.<br/>");
		}
		$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 <br/> 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.

Adapter Solves Incompatible Interface Problem

Supposing that the PlainDataEntry class is in the middle of a complex program, and all you want to do is to slip in another class that better protects your code from injection attacks. (What the heck! Why not also throw in a couple of validation routines too?) So our new interface and class look like the following:

<?php
//ICleanData.php
interface ICleanData
{
    function prepareData();
    function insertData();
}
?>
 
<?php
class CleanDataEntry implements ICleanData
{
    private $cusname;
    private $cusemail;
    private $cusurl;
    private $sql;
    private $tableMaster;
    private $hookup;
 
    public function __construct()
    {
        $this->tableMaster="injectAdapt";
        $this->hookup=UniversalConnect::doConnect();
    }
 
    function prepareData()
    {
        //Protect against injection attack
        $this->cusname =$this->hookup->real_escape_string($_POST['cusName']);
        $this->cusemail =$this->hookup->real_escape_string($_POST['cusEmail']);
        $this->cusurl = $this->hookup->real_escape_string($_POST['cusUrl']);
 
        //Validation of Email format
        if(filter_var($this->cusemail, FILTER_VALIDATE_EMAIL)){
        echo $this->cusemail. " is valid. <br />";
        }
        else
        {
            echo $this->cusemail . " is not a valid email. <br />";
            echo "<a href='AdddData.html'>Re-enter email and try again</a>";
            exit();
        }
 
       //Validation of URL format 
        if(filter_var($this->cusurl, FILTER_VALIDATE_URL)){
        echo $this->cusurl. " is valid. <br />";
        }
        else
        {
            echo $this->cusurl . " is not a valid URL. <br />";
            echo "<a href='AdddData.html'>Re-enter URL and try again</a>";
            exit();
        } 
    }
 
    //All of the cleaned up data can now go into the table
    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 <br/> 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 differences are relatively small between the PlainDataEntry and CleanDataEntry classes as far as structure is concerned. They have different interfaces, and that’s where the Adapter comes in. To resolve these different interfaces, the Adapter implements one interface, and makes it compatible with the other as you can see in the following listing:

<?php
//CleanupAdapter.php
class CleanupAdapter implements IDataEntry
{
   private $cleanData;
   public function __construct(ICleanData $cleanup)
   {
        $this->cleanData=$cleanup;
    }
 
    function getData()
    {
        $this->cleanData->prepareData();
    }
 
    function insertData()
    {
        $this->cleanData->insertData();
    } 
}
?>

The whole key to understanding the object Adapter is how it wraps one interface (ICleanData) in the constructor, and then implements it as part of the other interface it is implemented in. So the getData() and insertData() methods are instantiated as methods in the ICleanData interface. The type hinting in the constructor help remind us that design patterns emphasize programming to the interface rather than the implementation.

Now The Clients Gets Busy

So how do you wrap one interface into another? This is where the Client comes it. In make its request to the target (CleanDataEntry) through the adapter (CleanupAdapter). However, the adapter implements a different interface; so it creates an instance of the target and wraps it in an instantiation of the adapter.(By the way, an alternative name for the “Adapter” by the Gang of Four is “Wrapper.”) The requests appear as though they are through the original interface in the form of the getData() and insertData() methods.

<?php
//Client.php
function __autoload($class_name) 
{
    include $class_name . '.php';
}
class Client
{
   private $cleanData;
   private $adaptData;
 
   public function __construct()
   {
      $this->cleanData=new CleanDataEntry();
      $this->adaptData=new CleanupAdapter($this->cleanData);
      $this->adaptData->getData();
      $this->adaptData->insertData(); 
   }
}
$worker=new Client();
?>

At this point you can probably see why the Client class is considered a integral part of the Adapter design pattern. While it is still a requester class (essentially all that client classes are supposed to be), it must configure the request so that the Adapter participant can be used. You can think of the Client in this context as a requester/configuration class.

Why Bother?

After going over this, you may ask yourself,

Why bother with an Adapter?

After all, you could just use the CleanDataEntry class and be done with it. To understand the power of design patterns, big complex programs are more helpful. You have to suppose that you have a complex OOP program where the developer programmed to the interface. Rather than re-writing the whole program just to add a single module with a different interface, you use the Adapter, and then you don’t have to do any major code re-write. You just have to attach the Adapter and add your new module with the different interface. The Adapter handles all interface incompatibility issues, and you save a lot of time.

Like other design patterns, you don’t really need one until you really need one. Writing a few small modules here and there are easy to change. Fixing a monster program because your customer wants a change is where you will find design patterns helpful. Just like OOP programming in general, design patterns make the developer’s job easier when change and update is a constant feature of programming life. Simple programs have simple solutions. Complex programs have design patterns.

Share

Copyright © 2013 William Sanders. All Rights Reserved.

0 Responses to “PHP Adapter Pattern for Defense against Injection Attacks”


  • No Comments

Leave a Reply