note 93502 deleted from function.eval by danbrown

From: Date: Mon, 14 Sep 2009 02:01:14 +0000
Subject: note 93502 deleted from function.eval by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-160528@lists.php.net to get a copy of this message
Note Submitter: Crypton - blackcrypton at gmail dot com ---- I like the way (udo dot schroeter at gmail dot com's) script works so I have adapted it to include blacklisting of vars. Of course, you will want to adjust it to your environment. I use it so I can allow echo, print_r etc.. for example, but prevent access to vars that might be included on the page of execution and used in the site (such as common things like $db, $sql, etc..). <?php class SaferScript { var $source, $allowedCalls; function SaferScript($scriptText) { $this->source = $scriptText; $this->allowedCalls = array(); $this->blacklistVars = array(); } function allowHarmlessCalls() { // Whitelist overrides case switch below. $this->allowedCalls = explode(',', ' explode,implode,date,time,round,trunc,rand,ceil, floor,srand,strtolower,strtoupper,substr,stristr, strpos,print,print_r,echo' ); $this->blacklistVars = explode(',', 'db,sql,username,password,GLOBALS,_SERVER,_GET,_POST, _FILES_REQUEST,_SESSION,_ENV,_COOKIE,php_errormsg, HTTP_RAW_POST_DATA,http_response_header' ); } function parse() { $this->parseErrors = array(); $tokens = token_get_all('<?'.'php '.$this->source.' ?'.'>'); $vcall = ''; foreach ($tokens as $token) { if (is_array($token)) { $id = $token[0]; switch ($id) { case(T_VARIABLE): { $vcall .= 'v'; break; } case(T_STRING): { $vcall .= 's'; } case(T_NEW): case(T_RETURN): case(T_BREAK): case(T_EXIT): case(T_TRY): case(T_CATCH): case(T_CLONE): case(T_PRINT): case(T_ECHO): case(T_GLOBAL): case(T_INCLUDE): case(T_INCLUDE_ONCE): case(T_REQUIRE): case(T_REQUIRE_ONCE): case(T_FOR): case(T_WHILE): case(T_EVAL): case(T_FUNCTION): { if (array_search($token[1], $this->allowedCalls) === false) { $this->parseErrors[] = 'illegal call: '. $token[1]; } } } } else { $vcall .= $token; } if (stristr($vcall, 'v(') != '') { $this->parseErrors[] = array('Illegal Dynamic Function Call'); } foreach($this->blacklistVars as $blacklisted) { if (strpos($this->source, $blacklisted) !== false) { $this->parseErrors[] = 'Blacklisted Var: '. $blacklisted; } } if (sizeof($this->parseErrors) > 0) { return($this->parseErrors); } } } function execute($parameters = array()) { foreach ($parameters as $k => $v) { $k = $v; } if (sizeof($this->parseErrors) == 0) { eval($this->source); } } } ?> Examples: $testvars = array( '$GLOBALS', '$_SERVER' ); for ($i = 0; $i < count($testvars); $i++) { $mycode = 'print_r(' . $testvars[$i] . ');'; $test = new SaferScript($mycode); $test->allowHarmlessCalls(); print_r($test->parse()); $test->execute(); } Outputs: Array ( [0] => Blacklisted Var: GLOBALS ) Array ( [0] => Blacklisted Var: _SERVER ) include('"class.safeeval.php"); $mycode = '$hello = "Hello World!"; echo $hello;'; $test = new SaferScript($mycode); $test->allowHarmlessCalls(); print_r($test->parse()); $test->execute(); Outputs: Hello World!

« previous php.notes (#160528) next »