├── README └── safeeval.py /README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greysign/pysec/f990ba5ca87126c471142dca12f773b2a9addfba/README -------------------------------------------------------------------------------- /safeeval.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | #code by G 3 | #2010-11-20 4 | ''' 5 | 为序列化操作提供安全转换。 6 | 对eval数据进行词法分析,确保eval的数据中不会包含不合法的TRUE等写法, 7 | 并且在隔离、安全的环境执行eval。 8 | 用法: 9 | myobj = safe_eval(eval_str) 10 | ''' 11 | 12 | import re 13 | 14 | def safe_eval(eval_str,**kw): 15 | ''' 16 | 安全eval,确保eval的内容是合法的,并且隔离的。 17 | **kw不可用,以后扩展为可定义命名空间。 18 | ''' 19 | #callback functions 20 | def start_structure(scanner, token): return "start structure", token 21 | def key(scanner, token): return "key", token 22 | def value(scanner, token): 23 | #非法写法 24 | if token.lower() == 'true'and token != 'True': 25 | raise 'value Error "%s"'%token 26 | def str_value(scanner,token): 27 | return "string value",token 28 | def end_structure(scanner, token): return "end start structure",token 29 | 30 | scanner = re.Scanner([ 31 | (r"[{\[(]", start_structure), 32 | (r"[\w]+\s*:", key), 33 | (r"['\"][^'\"]+['\"]",str_value), 34 | (r"[\w]+", value), 35 | (r"\s*,\s*",None), 36 | (r"[})\]]", end_structure), 37 | ]) 38 | 39 | tokens, remainder = scanner.scan(eval_str) 40 | for token in tokens: 41 | print token 42 | #make a list of safe functions 43 | safe_list = ['math','acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'de grees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh'] 44 | #use the list to filter the local namespace s 45 | safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ]) 46 | #add any needed builtins back in. 47 | #由于所有内置的对象被屏蔽 __builtins__中的所有对象不可使用,所以True、False需要单独定义 48 | #加入命名空间 49 | safe_dict['True'] = True 50 | safe_dict['False'] = False 51 | return eval(eval_str,{'__builtins__':None},safe_dict) 52 | 53 | def test_ok(): 54 | print safe_eval("{1:'true',2:123,3:(True,[True])}") 55 | 56 | def test_bad(): 57 | print safe_eval("{1:'true',2:123,3:(True,[true])}") 58 | 59 | def test_bad2(): 60 | print safe_eval("__import__('os').system('dir')") 61 | 62 | 63 | if __name__ == '__main__': 64 | print eval("{1:'true',2:123,3:(True,[True])}") 65 | 66 | 67 | --------------------------------------------------------------------------------