note 90752 added to function.eval
| From: | tsdodo at gmail dot com | Date: | Fri, 08 May 2009 02:39:09 +0000 |
| Subject: | note 90752 added to function.eval | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-154342@lists.php.net to get a copy of this message | ||
Following is my script to validate code safety which also takes into account all lambda function
cases. Call is_eval_safe with PHP code and specify the whitelist for symbols (functions, classes,
etc.) and it returns to you whether or not you should evaluate it.
<?php
/**
* Permits evaluation of only whitelisted syntax
* Require whitelisting:
* declare, eval, global, include, include_once,
* require, require_once, throw, unset, use,
* and all functions, methods, and classes
*
* @param string $scriptText Script to evaluate
* @param array $functions Allowed functions
* @return true if the script is safe to evaluate
*/
function is_eval_safe($scriptText, $symbols)
{
$tokens = token_get_all("<?php $scriptText?>");
return safe_code($tokens, $symbols, 1, count($tokens) - 1);
}
function safe_code($tokens, $symbols, $start, $end) {
static $checkTokens = array(
T_DECLARE=>0, T_EVAL=>0, T_EXIT=>0, T_FUNCTION=>0,
T_GLOBAL=>0, T_INCLUDE=>0, T_INCLUDE_ONCE=>0, T_REQUIRE=>0,
T_REQUIRE_ONCE=>0, T_STRING=>0, T_THROW=>0, T_UNSET=>0,
T_UNSET_CAST=>0, T_USE=>0, T_VARIABLE=>0);
$symbols = array_change_key_case(array_flip($symbols))
+ array('array'=>0, 'true'=>0, 'false'=>0,
'null'=>0);
if(isset($symbols['unset']) || isset($symbols['(unset)'])) {
$symbols += array('unset'=>0, '(unset)'=>0);
}
if(isset($symbols['include']) || isset($symbols['include_once'])
|| isset($symbols['require']) || isset($symbols['require_once'])) {
$symbols += array(
'include'=>0, 'include_once'=>0, 'require'=>0,
'require_once'=>0);
}
for($i = $start; $i < $end; ++$i) {
$token = $tokens[$i];
if(is_array($token) && isset($checkTokens[$token[0]])) {
if($token[0] === T_VARIABLE) {
$i = safe_var($tokens, $symbols, $i + 1, $end);
if($i === false) {
return false;
}
} else if(!isset($symbols[strtolower($token[1])])) {
return false;
}
}
}
return true;
}
function safe_var($tokens, $symbols, $start, $end) {
while($start < $end && $tokens[$start][0] === T_WHITESPACE) {
++$start;
}
if($start >= $end) {
return false;
}
if($tokens[$start] !== '[') {
return $tokens[$start] === '(' ? false : $start;
}
$depth = 1;
for($i = $start + 1; $i < $end; ++$i) {
if($tokens[$i] === '[') {
++$depth;
continue;
}
if($tokens[$i] === ']') {
--$depth;
}
if($depth === 0) {
if(!safe_code($tokens, $symbols, $start, $i - $start - 1)) {
return false;
}
break;
}
}
return safe_var($tokens, $symbols, $i + 1, $end);
}
?>
----
Server IP: 209.41.74.194
Probable Submitter: 131.193.225.76
----
Manual Page -- http://www.php.net/manual/en/function.eval.php
Edit -- https://master.php.net/note/edit/90752
Del: integrated -- https://master.php.net/note/delete/90752/integrated
Del: useless -- https://master.php.net/note/delete/90752/useless
Del: bad code -- https://master.php.net/note/delete/90752/bad+code
Del: spam -- https://master.php.net/note/delete/90752/spam
Del: non-english -- https://master.php.net/note/delete/90752/non-english
Del: in docs -- https://master.php.net/note/delete/90752/in+docs
Del: other reasons-- https://master.php.net/note/delete/90752
Reject -- https://master.php.net/note/reject/90752
Search -- https://master.php.net/manage/user-notes.php