eval :
이것은 매우 강력하지만 신뢰할 수없는 입력에서 평가하기 위해 문자열을 수락하면 매우 위험합니다. 평가되는 문자열이 "os.system ( 'rm -rf /')"이라고 가정하십시오. 실제로 컴퓨터의 모든 파일을 삭제하기 시작합니다.
ast.literal_eval :
파이썬 리터럴 또는 컨테이너 디스플레이를 포함하는 표현식 노드 또는 문자열을 안전하게 평가합니다. 제공된 문자열 또는 노드는 문자열, 바이트, 숫자, 튜플, 목록, dicts, 세트, 부울, 없음, 바이트 및 세트와 같은 Python 리터럴 구조로만 구성 될 수 있습니다.
통사론:
eval(expression, globals=None, locals=None)
import ast
ast.literal_eval(node_or_string)
예:
# python 2.x - doesn't accept operators in string format
import ast
ast.literal_eval('[1, 2, 3]') # output: [1, 2, 3]
ast.literal_eval('1+1') # output: ValueError: malformed string
# python 3.0 -3.6
import ast
ast.literal_eval("1+1") # output : 2
ast.literal_eval("{'a': 2, 'b': 3, 3:'xyz'}") # output : {'a': 2, 'b': 3, 3:'xyz'}
# type dictionary
ast.literal_eval("",{}) # output : Syntax Error required only one parameter
ast.literal_eval("__import__('os').system('rm -rf /')") # output : error
eval("__import__('os').system('rm -rf /')")
# output : start deleting all the files on your computer.
# restricting using global and local variables
eval("__import__('os').system('rm -rf /')",{'__builtins__':{}},{})
# output : Error due to blocked imports by passing '__builtins__':{} in global
# But still eval is not safe. we can access and break the code as given below
s = """
(lambda fc=(
lambda n: [
c for c in
().__class__.__bases__[0].__subclasses__()
if c.__name__ == n
][0]
):
fc("function")(
fc("code")(
0,0,0,0,"KABOOM",(),(),(),"","",0,""
),{}
)()
)()
"""
eval(s, {'__builtins__':{}})
위의 코드에서 ().__class__.__bases__[0]
객체 자체는 없습니다. 이제 모든 하위 클래스를 인스턴스화 했습니다. 여기서 주요 enter code here
목표는 n 이라는 하나의 클래스를 찾는 것입니다.
인스턴스화 된 서브 클래스에서 이의를 제기 code
하고 function
이의를 제기 해야합니다 . 이것은 CPython
객체의 서브 클래스에 액세스하고 시스템을 연결 하는 대체 방법입니다 .
파이썬 3.7부터 ast.literal_eval ()이 더 엄격 해졌습니다. 더 이상 임의의 숫자를 더하거나 뺄 수 없습니다.링크
ast.literal_eval("1 & 1")
오류가 발생하지만eval("1 & 1")
그렇지 않습니다.