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'; ?>