작성일자 : 2024-01-04
Ver 0.1.1
0. Intro
Pyhon 코딩시 자주 사용되는 함수는 아니지만, 특별한 경우에는 꼭 eval 함수를 사용해서 처리하게 되는 경우도 종종 있긴 하다.
그런데 이 Python 내장 함수 eval은 유용하면서 동시에 사용시 상당히 주의를 기울여야 되는 위험한 함수기도 하다.
양날의 검인 eval 함수. 이번 포스팅을 통해 eval 함수에 대해 정리해보겠다.
1. eval(expression)
python3 문서에서는 eval()에 대해 다음과 같이 설명하고 있다.
```
eval(expression[, globals[, locals]])
...
인자는 '문자열 및 선택적 globals 및 locals'다. (...)
반환 값은 계산된 표현식의 결과입니다.
```
즉 문자열이나 표현식, 변수들을 입력으로 받아 이를 계산하고 반환해주는 함수이다.
단, 문자열, 표현식, 변수들이 모두 str 타입이어야 한다.
2. 예제
# 파이썬 eval(expression) 예제
# 1. 문자열 덧셈
a = eval('"Just Do It" + " - Nike -"')
print(f"1. eval('\"Just Do It\"' + '\" - Nike -\"') : {a}")
>>> 1. eval('"Just Do It"' + '" - Nike -"') : Just Do It - Nike -
# 2. 숫자 덧셈
b = eval("100 + 17")
print(f'2. eval("100 + 17") : {b}')
>>> 2. eval("100 + 17") : 117
# 3. 내장 함수 abs
c = eval("abs(-17)")
print(f'3. eval("abs(-17)") : {c}')
>>> 3. eval("abs(-17)") : 17
# 4. 리스트 길이
d = eval("len([1,2,3,4])")
print(f'4. eval("len([1,2,3,4])") : {d}')
>>> 4. eval("len([1,2,3,4])") : 4
# 5. round 함수
e = eval("round(1.5)")
print(f'5. eval("round(1.5)") : {e}')
>>> 5. eval("round(1.5)") : 2
3. 주의사항
참고 사이트 : https://bluese05.tistory.com/64
위 예제를 보면 eval 은 굉장히 사용성이 넓고 유용하다고 생각할 수 있다.
하지만, eval 은 이러한 자유로움이 장점이지만 동시에 이러한 자유로움으로 인해 발생할 수 있는 커다란 위험을 내포하고 있다.
아래와 같은 간단한 함수를 만들었다고 가정해보자.
x = str(input(">> input some text for mathematical expression : ")
print eval(x)
사용자에게 수학 표현식을 문자열로 받고, 계산 결과값을 출력해주는 간단한 함수이다.
하지만 이때 사용자가 아래와 같이 입력을 하면 어떻게 될까.
>> input some text for mathematical expression: __import__('os').system('ls /')
Applications Volumes home tmp
Developer bin installer.failurerequests usr
Library cores macOS Install Data var
Network data net
System dev private
Users etc sbin
서버의 root 디렉토리의 정보가 그대로 노출되었다.
이와 같이 eval() 함수는 해당 표현식을 그대로 실행하는 것이기 때문에 Command Injection Flaws 를 그대로 노출할 수 있으며 대형 참사로 이어질 수 있다. 이는 Python 뿐만 아니라 시스템 명령을 삽입할 수 있는 스크립트 언어(PHP, Javascript 등)은 모두가 가지고 있는 취약점이기도 하다.
뿐만 아니라, eval() 명령은 코드의 가독성을 떨어뜨리고 디버깅을 어렵게 만들수 있다.
또한 eval을 사용해 일부 로컬 환경에 의존하도록 구현할 경우 환경 의존성도 생길 수 있으므로 되도록 사용하지 않는 방향을 권장한다.