Script Protection and Input Screening

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
sam159
Forum Newbie
Posts: 5
Joined: Wed Oct 04, 2006 11:09 am
Location: Hull, UK

Script Protection and Input Screening

Post by sam159 »

Hi,
Here are a couple of classes that i use in my websites to make them more secure, free to use for anyone who might find them useful :)

security.php this searches for php tags and possible scripting in $_REQUEST

Code: Select all

<?php
class Security
{
	function __construct()
	{
		$this->ScriptProtection();
	}
	function ScriptProtection()
    {
        $disalowedtags = array(	"script",
	                       		"object",
	                       		"iframe",
	                       		"image",
	                       		"applet",
	                       		"meta",
	                       		"form",
	                       		"onmouseover",
	                       		"onmouseout");
    	foreach ($_REQUEST as $key => $value)
		{
            foreach ($disalowedtags as $tagname => $tagvalue)
            {
				if (eregi("<[^>]*".$tagvalue."*\"?[^>]*>", $value))
	    			{
                	$this->showError("Fatal Error","Illegal Tag Found In Request",$tagvalue,__LINE__,"NORM",True);
	    			}
            }
	    	if (eregi("((<|%3C)\?php|(<|%3C)\?)",$value))
	    		{
                $this->showError("Fatal Error","Illegal Tag Found In Request","php tag",__LINE__,"NORM",True);
	        	}
	    	/*if (eregi("(<|%3C)%",$value))
	    		{
                $this->showError("Fatal Error","Illegal Tag Found In Request","",__LINE__,"NORM",True);
	        	}*/
	    	if (eregi("(<|%3C)script",$value))
	    		{
                $this->showError("Fatal Error","Illegal Tag Found In Request","script",__LINE__,"NORM",True);
	        	}
    	}

    }
	function showError($ErrorTitle,$ErrorText,$AdditionalText,$LineNumber,$Type="NORM",$KillScript=False)
    {
	    if ($Type == "NORM")
	    {
		    echo "<TABLE BORDER=0 width=500>\n";
		    echo "<TR><TD BGCOLOR=\"#A73636\" COLSPAN=2><div align=\"center\"><h2>".$ErrorTitle."</h2></div></TD></TR>\n";
		    echo "<TR><TD BGCOLOR=\"#A73636\">". "Error :" ."</TD><TD>". $ErrorText ."</TD></TR>\n";
            if ($AdditionalText != "")
            {
            	echo "<TR><TD BGCOLOR=\"#A73636\">". "Additional Info :" ."</TD><TD>". $AdditionalText ."</TD></TR>\n";
            }
            echo "<TR><TD BGCOLOR=\"#A73636\">". "Line Number" ."</TD><TD>".$LineNumber."</TD></TR>\n";
            echo "<TR><TD BGCOLOR=\"#A73636\">". "Links" ."</TD><TD><a href=\"index.php\">Index</a></TD></TR>\n";
		    echo "<TR><TD BGCOLOR=\"#A73636\" COLSPAN=2>". "If this problem persists, please email the admin at <a href=\"mailto:sam@xnet.tk\">sam@xnet.tk</a>, stating the above error and any additional info" ."</TD></TR>\n";
			echo "</TABLE>\n";
	    }
        elseif ($Type == "INLINE")
        {
        	if (isset($AdditionalText) && !empty($AdditionalText))
            {
             	$AdditionalText = " ( ".$AdditionalText." ) ";
            }
			echo ("<font style=\"background-color:A73636; color:FFFFFF\">".$ErrorTitle." : ".$ErrorText.$AdditionalText."</font><BR />");
        }
        if ($KillScript == True)
        {
            die();
        }
	}
}
?>
input.php This can screen inputs and only allow certain characters, it also sets $_REQUEST, $_GET, and $_POST to null, and stores them internally, so that unscreened inputs cant be used, if its needed theres the GetRaw function.

Code: Select all

<?php
class Input
{
	private $REQUEST;
    private $GET;
    private $POST;
function __construct()
{
	$this->REQUEST = $_REQUEST;
    $_REQUEST = null;
    $this->GET = $_GET;
    $_GET = null;
    $this->POST = $_POST;
    $_POST = null;
}
function GetRequestVar($name)
    {
    	if (!empty($this->REQUEST[$name]))
        {
        	return $this->REQUEST[$name];
        }
        else
        {
        	return false;
        }
    }
function ValidateVar($pattern,$name)
{
    $theVar = $this->GetRequestVar($name);
	if ($theVar != false)
    {
    	$cleaned = ereg($pattern,$theVar);
        if ($cleaned)
        {
        	return $theVar;
        }
        else
        {
        	return false;
        }
    }
    else
    {
    	return false;
    }
}
function GetAlpha($name)
{
	$theVar = $this->ValidateVar("^[A-Za-z0-9\.,' _-]+$",$name);
    return $theVar;
}
function GetInt($name)
{
	$theVar = $this->ValidateVar("^[0-9]+$",$name);
    return $theVar;
}
function GetFloat($name)
{
	$theVar = $this->ValidateVar("^[0-9]+(\.[0-9]+)?$",$name);
    return $theVar;
}
function GetEmail($name)
{
	$theVar = $this->ValidateVar("^.+@.+\..+$",$name);
    return $theVar;
}
function GetRaw($name)
{
	return $this->REQUEST[$name];
}
}
?>
Example use

Code: Select all

<?php
require "security.php";
require "input.php";
$sec = new Security();
$in = new Input();

$userInput = $in->GetAlpha("input");
$userEmail = $in->GetEmail("email");
$blah = $_GET['blah']; //Doesnt Work, as $_GET is null
?>
User avatar
Technocrat
Forum Contributor
Posts: 127
Joined: Thu Oct 20, 2005 7:01 pm

Post by Technocrat »

Might want to take a look at:
viewtopic.php?t=47340

Also you probably want to convert html entities to ascii, remove newlines, and spaces more than one. These tricks can bypass your filter as it is.
LiveFree
Forum Contributor
Posts: 258
Joined: Tue Dec 06, 2005 5:34 pm
Location: W-Town

Post by LiveFree »

Take a look at using the preg_* functions and the PCRE style-regex
Post Reply