신뢰할 수없는 문자열에 대한 Python 's Eval ()의 보안?
문제
Eval ()을 사용하여 Python 문자열을 평가하고 다음과 같은 클래스가있는 경우.
class Foo(object):
a = 3
def bar(self, x): return x + a
문자열을 신뢰하지 않으면 보안 위험은 무엇입니까? 특히:
- ~이다
eval(string, {"f": Foo()}, {})
위험한? 즉, FOO 인스턴스에서 OS 또는 SYS 또는 안전하지 않은 것에 도달 할 수 있습니까? - ~이다
eval(string, {}, {})
위험한? 즉, Len 및 List와 같은 Buildins에서 OS 또는 SYS에 전적으로 도달 할 수 있습니까? - Eval Context에서 BuildIns를 전혀 존재하지 않는 방법이 있습니까?
[0] * 1000000000"과 같은 안전하지 않은 문자열이 있습니다. 최악의 경우 프로그램을 느리게/중지하기 때문입니다. 나는 주로 프로그램 외부의 사용자 데이터를 보호하는 것에 대해 우려하고 있습니다.
확실히, eval(string)
사용자 정의 사전이 없으면 대부분의 경우 안전하지 않습니다.
해결책
이와 같은 블랙리스트 접근법으로 평가를 보호 할 수 없습니다. 보다 평가는 정말 위험합니다 CPYTHON 통역사를 segfault로 만드는 입력의 예는 원하는 클래스에 액세스 할 수 있습니다.
다른 팁
eval()
악의적 인 데이터가 전체 시스템을 손상시키고, 고양이를 죽이고, 개를 먹고, 아내를 사랑할 수 있습니다.
최근에는 Python-Dev 목록에서 이런 종류의 일을 안전하게 수행하는 방법에 대한 스레드가 있었으며 결론은 다음과 같습니다.
- 이 작업을 제대로하기가 정말 어렵습니다.
- 많은 종류의 공격을 차단하려면 Python 통역사에 패치가 필요합니다.
- 당신이 정말로 원하지 않는 한 그렇게하지 마십시오.
도전에 대해 읽으려면 여기서 시작하십시오. http://tav.espians.com/a-challenge-to-break-python-security.html
어떤 상황에서 Eval ()를 사용하고 싶습니까? 사용자가 임의의 표현식을 실행할 수 있기를 원하십니까? 아니면 어떤 식 으로든 데이터를 전송하고 싶습니까? 아마도 어떤 식 으로든 입력을 잠그는 것이 가능할 것입니다.
당신은 갈 수 있습니다 os
내장 기능 사용 : __import__('os')
.
Python 2.6+의 경우 AST 모듈 도움이 될 수 있습니다. 특히 ast.literal_eval
, 그것은 당신이 평가하고 싶은 것에 달려 있지만.
빈 사전을 Eval ()로 전달하더라도 일부 구문 트릭을 사용하여 Segfault (C) Python이 여전히 가능합니다. 예를 들어, 통역사에서 이것을 시도하십시오. eval("()"*8**5)
질문을 끄는 것이 좋습니다.
- 어떤 종류의 표현을 평가하고 싶습니까?
- 좁게 정의 된 구문과 일치하는 문자열 만 Eval () D인지 확인할 수 있습니까?
- 그런 다음 고려하십시오 저것 는 안전하다.
예를 들어, 사용자가 평가를 위해 대수 표현식을 입력하도록하려면 하나의 문자 변수 이름, 숫자 및 특정 연산자 및 함수 세트로 제한하는 것을 고려하십시오. 다른 것을 포함하는 문자열을 평가하지 마십시오.
아주 좋은 것이 있습니다 비 안전에 관한 기사 eval()
Mark Pilgrim 's에서 파이썬으로 뛰어 들었습니다 지도 시간.
이 기사에서 인용 :
결국, 실생활에서 크게 유용하지 않은 것으로 밝혀진“안전한”정의에 대해 신뢰할 수없는 파이썬 표현을 안전하게 평가할 수 있습니다. 당신이 그냥 놀고 있다면 괜찮습니다. 신뢰할 수있는 입력 만 통과하면 괜찮습니다. 그러나 다른 것은 단지 문제를 요구하는 것입니다.