note 90752 deleted from function.eval by danbrown

From: Date: Sun, 17 May 2009 19:49:57 +0000
Subject: note 90752 deleted from function.eval by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-155275@lists.php.net to get a copy of this message
Note Submitter: tsdodo at gmail dot com ---- 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); } ?>

« previous php.notes (#155275) next »