note 75389 added to function.eval

From: Date: Sat, 26 May 2007 18:40:12 +0000
Subject: note 75389 added to function.eval
Groups: php.notes 
Request: Send a blank email to php-notes+get-126938@lists.php.net to get a copy of this message
Safer Eval eval() is used way to often. It slows down code, makes it harder to maintain and it created security risks. However, sometimes, I found myself wishing I could allow some user-controlled scripting in my software, without giving access to dangerous functions. That's what the following class does: it uses PHP's tokenizer to parse a script, compares every function call against a list of allowed functions. Only if the script is "clean", it gets eval'd. <?php class SaferScript { var $source, $allowedCalls; function SaferScript($scriptText) { $this->source = $scriptText; $this->allowedCalls = array(); } function allowHarmlessCalls() { $this->allowedCalls = explode(',', 'explode,implode,date,time,round,trunc,rand,ceil,floor,srand,'. 'strtolower,strtoupper,substr,stristr,strpos,print,print_r'); } 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_REQUIRE_ONCE): case(T_REQUIRE): case(T_NEW): case(T_RETURN): case(T_BREAK): case(T_CATCH): case(T_CLONE): case(T_EXIT): case(T_PRINT): case(T_GLOBAL): case(T_ECHO): case(T_INCLUDE_ONCE): case(T_INCLUDE): 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'); return($this->parseErrors); } function execute($parameters = array()) { foreach ($parameters as $k => $v) $$k = $v; if (sizeof($this->parseErrors) == 0) eval($this->source); else print('cannot execute, script contains errors'); } } ?> Usage example: <?php $ls = new SaferScript('horribleCode();'); $ls->allowHarmlessCalls(); print_r($ls->parse()); $ls->execute(); ?> Of course it is not entirely safe, but it's a start ;-) ---- Server IP: 69.147.83.197 Probable Submitter: 84.168.231.39 ---- Manual Page -- http://www.php.net/manual/en/function.eval.php Edit -- https://master.php.net/note/edit/75389 Del: integrated -- https://master.php.net/note/delete/75389/integrated Del: useless -- https://master.php.net/note/delete/75389/useless Del: bad code -- https://master.php.net/note/delete/75389/bad+code Del: spam -- https://master.php.net/note/delete/75389/spam Del: non-english -- https://master.php.net/note/delete/75389/non-english Del: in docs -- https://master.php.net/note/delete/75389/in+docs Del: other reasons-- https://master.php.net/note/delete/75389 Reject -- https://master.php.net/note/reject/75389 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#126938) next »