신뢰할 수없는 코드 실행을위한 모범 사례


31

사용자가 내 서버에 대해 신뢰할 수없는 임의의 파이썬 코드 ( 이와 비슷한 비트 ) 를 실행할 수 있도록 해야하는 프로젝트가 있습니다. 저는 파이썬을 처음 접했고 시스템에 보안 허점이나 다른 취약점을 일으키는 실수를 피하고 싶습니다. 내 서비스를 유용하게 사용할 수 있지만 남용하지 않도록 할 수있는 모범 사례, 권장 사항 또는 기타 지침이 있습니까?

지금까지 내가 고려한 내용은 다음과 같습니다.

  • 와 같이 잠재적으로 위험한 패키지의 사용을 금지하려면 컨텍스트 __builtins__에서 제거하십시오 . 사용자는 내가 제공 한 패키지 만 사용할 수 있습니다.execos
  • 적절한 시간 초과를 적용하려면 스레드를 사용하십시오.
  • exec컨텍스트 내에서 할당 할 수있는 총 메모리 양을 제한하고 싶지만 가능한지 확실하지 않습니다.

straight에 대한 대안이 있지만 여기에서 어떤 exec것이 도움이 될지 잘 모르겠습니다.

  • ast.NodeVisitor안전하지 않은 개체에 액세스하려는 시도를 포착하려면를 사용하십시오 . 그러나 어떤 물건을 금지해야합니까?
  • 입력에서 이중 밑줄을 검색합니다. (위의 옵션보다 덜 우아합니다).
  • 사용 PyPy또는 이와 유사한하면 코드를 샌드 박스.

참고 : JavaScript 기반 인터프리터가 하나 이상 있다는 것을 알고 있습니다. 내 시나리오에서는 작동하지 않습니다.



3
@MartijnPieters : 훌륭합니다. 각각을 요약하면 답을 얻을 가치가 있습니다.
Robert Harvey

디스크에 남은 쓰레기, 네트워크 (스팸 등을 보내지 않도록 함), 다른 파일에 대한 권한 (파일 읽기)도 고려하십시오. while 루프를 꺼내면 CD 메커니즘이 손상 될 수 있습니다 ... 가상화 (감옥이나 이름을 지정한 일부 kvm) 또는 최소한 권한이없는 사용자가됩니다. 자신의 프로그램을 활용할 수 있도록 합리적인 수준의 메모리를 설정하십시오.
kyticka


1
시도 PyPy를 :> 샌드 박싱을 : PyPy는 완전히 안전한 방법으로 신뢰할 수없는 코드를 실행할 수있는 기능을 제공합니다.
Vorac

답변:


28

파이썬 샌드 박싱은 어렵다 . 파이썬은 본질적으로 여러 단계에서 내성적입니다.

즉, 해당 유형 자체에서 특정 유형에 대한 팩토리 메소드를 찾고 해석기가 직접 제한없이 실행하는 새로운 하위 레벨 오브젝트를 구성 할 수 있습니다.

다음은 Python 샌드 박스에서 벗어날 수있는 창의적인 방법을 찾는 몇 가지 예입니다.

기본 아이디어는 항상 기본 파이썬 유형을 만드는 방법을 찾는 것입니다. 파이썬 인터프리터가 임의의 (체크되지 않은!) 바이트 코드를 실행하도록하여 함수와 클래스를 호출하고 셸에서 벗어날 수 있습니다.

exec명령문 에도 동일하게 적용됩니다 ( exec()Python 3의 함수).

따라서 다음을 원합니다.

  • 밑줄로 시작하는 이름에 대한 액세스를 제거하기 위해 Python 코드의 바이트 컴파일을 엄격하게 제어하거나 적어도 바이트 코드를 사후 처리하십시오.

    이를 위해서는 파이썬 인터프리터의 작동 방식과 파이썬 바이트 코드의 구조에 대한 자세한 지식이 필요합니다. 코드 객체는 중첩됩니다. 모듈의 바이트 코드는 최상위 수준의 문장 만 다루고, 각 함수와 클래스는 예를 들어 중첩 된 함수와 클래스에 대한 다른 바이트 코드 객체를 포함하는 메타 데이터로 구성됩니다 .

  • 사용할 수있는 모듈 을 허용 목록에 추가해야합니다 . 면밀히.

    파이썬 모듈은 다른 모듈에 대한 참조를 포함 합니다. 를 가져 오면 모듈 네임 스페이스에 모듈을 os나타내는 로컬 이름 os이 있습니다 os. 이로 인해 결정된 공격자가 모듈을 샌드 박스에서 벗어날 수 있습니다. pickle모듈은, 예를 들어, 당신이 그렇게하면, 예를 들어 임의의 코드가 객체를로드 할 수 있는 받는 사람의 허용 된 모듈 리드를 통해 경로 pickle모듈, 당신은 여전히 문제가 있습니다.

  • 시간 할당량을 엄격하게 제한해야합니다. 가장 중립적 인 코드조차도 리소스를 묶어 영원히 실행을 시도 할 수 있습니다.

엄격한 바이트 코드 컨트롤을 제공하는 RestrictedPython을 살펴보십시오 . RestrictedPythonPython 코드를 Python 2.3에서 2.7까지 허용되는 이름, 모듈 및 객체를 제어 할 수있는 것으로 변환합니다.

RestrictedPython귀하의 목적을 위해 충분히 안전한 경우 구현하는 정책에 따라 다릅니다. 밑줄로 시작하는 이름에 대한 액세스를 허용하지 않고 모듈을 엄격히 화이트리스트에 올리는 것이 시작입니다.

내 견해로는 유일하게 강력한 옵션은 외부 세계에 대한 네트워크 액세스 권한이없는 별도의 가상 컴퓨터를 사용하는 것입니다. 각각의 새 스크립트에는 새로운 VM이 대신 제공됩니다. 그렇게하면 코드가 Python 샌드 박스에서 벗어날 수 있지만 (아마도 그렇지는 않음) 모든 공격자가 액세스 할 수있는 수명이 짧고 가치가 없습니다.


10

TL; DR chroot / jail을 사용하고 권한없이 사용자 정의 사용자로 실행하십시오.

신뢰할 수없는 코드를 실행하는 가장 좋은 방법은 시스템 샌드 박스 를 통해 코드를 분리하는 것 입니다. 최대한의 보안을 위해 :

  • 파이썬 만 있고 컨테이너의 의존성과 컨테이너의 의존성이있는 컨테이너를 만듭니다.
  • 꼭 필요한 것은 아닌 모든 장치 (예 : 네트워크 및 스토리지) 없이 컨테이너를 만듭니다 .
  • 메모리 및 프로세스 사용에 제한이있는 컨테이너를 만듭니다.
  • 모든 실행마다 (또는 최소한 각 고유 사용자 및 최대 기간 마다) 컨테이너를 다시 작성하십시오.
  • 필요한 최소 권한을 가진 사용자로 실행
  • 파일을 쓸 수있는 권한이없는 사용자로 실행

또한 chroot에서 안전하게 작업을 수행하기위한 표준 사례를 따릅니다. 각 호출마다 chroot의 파일 시스템을 다시 빌드 할 수 있으며 특히 편집증입니다. 일반적으로 사용자는 chroot가 실행되는 파일 시스템을 수정할 수 없습니다.


이것은 원격으로 확실하게 확신 할 수있는 유일한 방법입니다. 자체 프로세스를 제공하십시오.
Michael Kohne

3

안전하게 할 수있는 방법은 없습니다.

이와 같은 작업을 안전하게 수행하려면 완전히 제어 된 환경에서 실행되는 시스템을 사용하지 말고 사용자 브라우저에서 실행하는 자체 Python 구현을 시작해야합니다. Jython (python for java)으로 시작하여 Java 애플릿으로 패키지 할 수 있습니다. 사용자의 컴퓨터에서 java 샌드 박스에서 실행되므로 시스템이 상당히 안전합니다.


4
안전 문제는 클라이언트 시스템이 아니라 서버에 대한 것이 었습니다. 다른 웹 기술과 마찬가지로 Java의 잠재적 보안 위험은 서버가 클라이언트에 위험한 프로그램을 배포하는 데 사용될 수 있다는 것입니다.
ddyer

1
@grasGendarme은 비행기 추락에 관한 새로운 이야기와 매우 흡사합니다. 자바 보안 허점에 대한 이야기는 자바가 비교적 안전하다는 것을 말해줍니다. C에 대한 그런 이야기는 결코 얻지 못할 것입니다. 응답이 "좋아요. 실행하면 원하는대로 할 수 있습니다"
Richard Tingle

2

Martijn이 위에서 말했듯이 이것은 파이썬에서 실제로 정말 어렵습니다. 파이썬은 무관심하기 때문에 언어 기능을 제한하여 가능하다고 생각하지 않습니다. 그리고 한 버전의 Python에서 작동하는 샌드 박스를 얻는다면 다음 버전이이를 깨뜨릴 수 있습니다.

표준 CPython 대신 PyPy 를 살펴볼 것 입니다. 요컨대, 그것은 파이썬의 호환되는 대안적인 구현입니다. 여기에는 몇 가지 장점과 고유 한 기능이 있으며 그 중 하나는 언어 기능을 제한하는 대신 시스템 호출을 대체하여 샌드 박싱하는 것입니다.


0

성능이 크게 중요하지 않은 한 항상 Brython에서 실행하여 JavaScript 샌드 박스에 효과적으로 배치 할 수 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.