Fix (interpreter security): builtins functions passed as tools enable the use of compile, eval, exec (#274)
This commit is contained in:
		
							parent
							
								
									7a91123729
								
							
						
					
					
						commit
						a4612c98dc
					
				|  | @ -604,6 +604,8 @@ def evaluate_call( | ||||||
|             # cap the number of lines |             # cap the number of lines | ||||||
|             return None |             return None | ||||||
|         else:  # Assume it's a callable object |         else:  # Assume it's a callable object | ||||||
|  |             if (func in [eval, compile, exec]) and (func not in static_tools.values()): | ||||||
|  |                 raise InterpreterError(f"Invoking eval, compile or exec is not allowed ({func_name}).") | ||||||
|             return func(*args, **kwargs) |             return func(*args, **kwargs) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -916,4 +916,37 @@ shift_intervals | ||||||
|         code = 'capitals = {"Czech Republic": "Prague", "Monaco": "Monaco", "Bhutan": "Thimphu"};capitals["Butan"]' |         code = 'capitals = {"Czech Republic": "Prague", "Monaco": "Monaco", "Bhutan": "Thimphu"};capitals["Butan"]' | ||||||
|         with pytest.raises(Exception) as e: |         with pytest.raises(Exception) as e: | ||||||
|             evaluate_python_code(code) |             evaluate_python_code(code) | ||||||
|         assert "Maybe you meant one of these indexes instead" in str(e) and "['Bhutan']" in str(e).replace("\\", "") |         assert "Maybe you meant one of these indexes instead" in str( | ||||||
|  |             e | ||||||
|  |         ) and "['Bhutan']" in str(e).replace("\\", "") | ||||||
|  | 
 | ||||||
|  |     def test_dangerous_builtins_calls_are_blocked(self): | ||||||
|  |         unsafe_code = "import os" | ||||||
|  |         dangerous_code = f""" | ||||||
|  | exec = callable.__self__.exec | ||||||
|  | compile = callable.__self__.compile | ||||||
|  | exec(compile('{unsafe_code}', 'no filename', 'exec')) | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  |         with pytest.raises(InterpreterError): | ||||||
|  |             evaluate_python_code(unsafe_code, static_tools=BASE_PYTHON_TOOLS) | ||||||
|  | 
 | ||||||
|  |         with pytest.raises(InterpreterError): | ||||||
|  |             evaluate_python_code(dangerous_code, static_tools=BASE_PYTHON_TOOLS) | ||||||
|  | 
 | ||||||
|  |     def test_dangerous_builtins_are_callable_if_explicitly_added(self): | ||||||
|  |         dangerous_code = """ | ||||||
|  | compile = callable.__self__.compile | ||||||
|  | eval = callable.__self__.eval | ||||||
|  | exec = callable.__self__.exec | ||||||
|  | 
 | ||||||
|  | eval("1 + 1") | ||||||
|  | exec(compile("1 + 1", "no filename", "exec")) | ||||||
|  | 
 | ||||||
|  | teval("1 + 1") | ||||||
|  | texec(tcompile("1 + 1", "no filename", "exec")) | ||||||
|  |         """ | ||||||
|  | 
 | ||||||
|  |         evaluate_python_code( | ||||||
|  |             dangerous_code, static_tools={"tcompile": compile, "teval": eval, "texec": exec} | BASE_PYTHON_TOOLS | ||||||
|  |         ) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue