메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

모인모인의 보안 위험이 주는 교훈 (learning from mistakes)

한빛미디어

|

2002-08-16

|

by HANBIT

5,960

저자: 스티브 피긴스(Stephen Figgins), 역 전순재

필자가 파이썬의 위키 프로그램(Python wiki program)인 모인모인(MoinMoin)에 대한 사설을 새롭게 쓰자 마자 위르겐 헤르만(Jugen Hermann)은 다음과 같은 주의와 함께 새로운 버전을 선언하였다.
이 버전은 보안 업데이트이다. 이 때문에 긴급히 배포하게 되었다. 수정된 버전은 exec() 호출들을 __import__()로 대체한다. 이렇게 하는 것이 훨씬 더 안전하다 (실제로는, 완전하게 불안전한 것과 대비해 보았을 때 안전하다). 만약 배포 버전 0.5 또는 0.6을 설치하였다면, 당장 업그레이드 하라!
짧은 배포 주기 때문에 코드가 0.6이든 0.7이든 큰 차이가 있지는 않을 것이다. 그래서 바뀐 부분들을 쉽게 찾을 수 있다. 필자는 무엇인가 배울 기회가 있다는게 너무 좋다. 0.6 버전의 복사본을 하나 얻어서 0.7과 비교해보았다. 모인모인에는 헤르만이 같은 코드를 사용하기를 원했지만 결국 서로 다른 라이브러리 중의 하나를 그 코드가 사용하도록 선택한 곳이 여러 군데 있었다. 이것을 이른바 플러그-인이라고 부른다. 헤르만은 플러그-인을 사용하여 마임-형(mime-type)[1]에 따라 포매터[2]들을 선택하거나 폼[3]으로부터 제출되는 정보의 형에 따라 특수한 해석기(parser)나 확장 마크로 집합을 선택한다. 사용할 플러그-인의 이름은 CGI가 건네주는 정보로부터 얻는다.

예를 들어, 다음 코드는 포메터를 임포트하기 위해 사용된다.
exec("from formatter.%s import Formatter" %
    (string.replace(mimetype, "/", "_"),))
그렇지만 mimetype은 신뢰할 수 없는 바깥쪽 소스에 있는 프로그램에 건네지는 정보로부터 얻는다. 보안상 그렇게 큰 누수처럼 보이지 않을지도 모르지만 어떤 누수라도 위험한 것이다. 누군가 mimetype에 건네지는 문자열을 조작할 수 있기 때문이다. exec 함수는 건네지는 어떤 코드라도 실행할 것이다. exec을 사용해서 생각지 않게 위험한 코드 조각을 실행할 수도 있다. 다음은 헤르만이 어떻게 그 문제점을 고쳤는지 보여준다. 그는 이러한 exec 문자열들을 다음 유틸리티 함수로 대체하였다.
def importName(modulename, name):
    """ Import a named object from a module in the context of this function,
        i.e. use fully qualified module paths.

        Return None on failure.
    """
    try:
        module = __import__(modulename, globals(), locals(), [name])
    except ImportError:
        return None
        
    return vars(module)[name]
__import__ 함수는 오로지 지정된 코드만을 임포트한다. 만약 (이 함수에 modulename으로 건네지는) mimetype이 조작되었다고 하더라도 여러분은 뜻밖의 침입자가 아니라 단지 임포트 에러를 맞이할 뿐이다.

이러한 종류의 에러들은 펄(Perl)에서는 taint 모드가 포착하도록 디자인되었다. 이 편집증환자(paranoid) 모드에서, 프로그램 외부에서 받아들인 정보는 이 경우의 mimetype에 할당되는 문자열처럼 정규 표현식에 의해서 점검되지 않는 한 오염(tainted)되었기 때문에 거부된다. 이 모드가 하나 더 추가해주는 단계는 여러분이 아무 생각없이 떠나기 전에 멈추어서 생각하도록 디자인되었다.

파이썬에는 taint 모드와 동등한 것은 없다. 그러나 위험하다고 여겨지는 코드를 제한하도록 도와주는 모듈은 있다. 이 모듈은 제한된 실행 모듈 또는 RExec 모듈이라고 불린다. 이 경우에는 RExec 모듈은 필요없다. 왜냐하면 설치된 코드만을 임포트할 필요가 있을 뿐이지 사용자가 제공한 코드를 평가할 필요가 있는 것은 아니기 때문이다. __import__ 함수는 이러한 목적을 훌륭하게 만족시킨다. 그렇지만 수많은 CGI와 작업할 경우 여러분은 Rexec에 대해 고려해 보아야 할 것이다.
[1] Multipurpose Internet Mail Extensions (다용도 인터넷 메일 확장): 마임 형은 "파일종류 / 파일포맷" 형태로 표현됨
[2] formatter(포매터): 문서의 형식을 특정 용도로 사용하기 위해 조작하는 프로그램(형식화기)
[3] form(폼) : 웹에서 정보를 입력 받을 때 사용하는 일정한 모양의 문서 양식(웹 입력양식)

스티브 피긴스(Stephen Figgins)는 오라일리 네트워크 편집자이자 파이썬 데브센터 책임자이다.
TAG :
댓글 입력
자료실