hnd_nonex = $h_nonex;
$this->hnd_overflow = $h_overflow;
$this->hnd_type = $h_type;
$this->hnd_method = $h_method;
}
// проверка GET переменных
public function CheckGetVars()
{
foreach ($_GET as $k=>$v) {
if (in_array($k, $this->ignore)) {
break;
}
if (!array_key_exists($k, $this->vars)) {
$this->PanicVarNotExist($k);
break;
}
if (in_array( 'in_post', $this->vars[$k][0]) ||
in_array( 'in_cookie', $this->vars[$k][0])) {
$this->PanicVarBadPlace($k);
}
$this->VarCheck($k, $v);
}
return true;
}
// проверка POST переменных
public function CheckPostVars()
{
foreach ($_POST as $k=>$v) {
if (in_array($k, $this->ignore)) {
break;
}
if (!array_key_exists($k, $this->vars)) {
$this->PanicVarNotExist($k);
break;
}
if (in_array('in_get',$this->vars[$k][0]) ||
in_array('in_cookie',$this->vars[$k][0])) {
$this->PanicVarBadPlace($k);
}
$this->VarCheck($k, $v);
}
return true;
}
// проверка COOKIE переменных
public function CheckCookieVars()
{
foreach ($_COOKIE as $k=>$v) {
if (in_array($k, $this->ignore)) {
break;
}
if (!array_key_exists($k, $this->vars)) {
$this->PanicVarNotExist($k);
break;
}
if (in_array('in_get',$this->vars[$k][0]) ||
in_array('in_post',$this->vars[$k][0])) {
$this->PanicVarBadPlace($k);
}
$this->VarCheck($k, $v);
}
return true;
}
// проверка всех переменных
public function CheckVars()
{
$this->CheckGetVars();
$this->CheckPostVars();
$this->CheckCookieVars();
}
// добавление правила для конкртеной переменной
private function AddVar($name, $type, $maxlength)
{
$this->vars[$name] = array($type, $maxlength);
}
//типы переменных
/**
num - число
alnum - строка из чисел или букв
char - один символ
print - печатаемый символ
если тип начинается с ~, то система сравнит его со строкой как регулярное выражение
*/
// проверка переменной по правилу
private function VarCheck($name, &$value)
{
foreach ($this->vars[$name][0] as $type) {
switch ($type) {
case 'num': if (!$this->is_num($value)) {
$this->PanicVarBadType($name);
return false;
}
break;
case 'alnum': if (!$this->is_alnum($value)) {
$this->PanicVarBadType($name);
return false;
}
break;
case 'char': if (!$this->is_char($value)) {
$this->PanicVarBadType($name);
return false;
}
break;
case 'print': if (!$this->is_print($value)) {
$this->PanicVarBadType($name);
return false;
}
break;
case '!num': if ($this->is_num($value)) {
$this->PanicVarBadType($name);
return false;
}
break;
case '!alnum': if ($this->is_alnum($value)) {
$this->PanicVarBadType($name);
return false;
}
break;
case '!char': if ($this->is_char($value)) {
$this->PanicVarBadType($name);
return false;
}
break;
default: if ($type[0] == '~' && !preg_match($type,$value)) {
$this->PanicVarBadType($name);
return false;
}
}
}
if (($this->vars[$name][1] != 0) &&
strlen($value) > $this->vars[$name][1]){
$this->PanicVarMaxLength($name);
return false;
}
return true;
}
// дальше идут функции, проверяющие переменную на принадлежность к
// соответсвтующему типу
private function is_num($value) { return is_numeric($value); }
private function is_alnum($value) { return ctype_alnum($value); }
private function is_char($value) { return (strlen($value) == 1); }
private function is_print($value) { return (ctype_print($value) || empty($value)); }
// функции, которые вызывают обработчики нарушений безопасности
private function PanicVarNotExist($varname)
{
if ($this->hnd_nonex) {
call_user_func($this->hnd_nonex, $varname);
}
}
private function PanicVarMaxLength($varname)
{
if ( $this->hnd_overflow ) {
call_user_func($this->hnd_overflow, $varname);
}
}
private function PanicVarBadType($varname)
{
if ($this->hnd_type) {
call_user_func($this->hnd_type, $varname);
}
}
private function PanicVarBadPlace($varname)
{
if ( $this->hnd_method ) {
call_user_func( $this->hnd_method, $varname );
}
}
}
//========================
// пример использования
$firewall_rules = array(
'news' => array( array('alnum') , 50),
'comment' => array( array('~.*~', 'in_post'), 1000),
);
function Firewall_nonex($varname)
{
exit('Hacking attempt - '.$varname.'
excess var');
}
function Firewall_overflow($varname)
{
exit('Hacking attempt - '.$varname.'
Length limit exceeded');
}
function Firewall_type($varname)
{
exit('Hacking attempt - '.$varname.'
Incorrect var type');
}
function Firewall_place($varname)
{
exit('Hacking attempt - '.$varname.'
bad var place');
}
$firewall = new WebFirewall('Firewall_nonex', 'Firewall_type', 'Firewall_overflow', 'Firewall_place');
$firewall->vars = $firewall_rules;
$firewall->CheckVars();
echo 'all ok';
?>