note 90752 added to function.eval

From: 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

« previous php.notes (#154342) next »