이 버전은 보안 업데이트이다. 이 때문에 긴급히 배포하게 되었다. 수정된 버전은 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이 조작되었다고 하더라도 여러분은 뜻밖의 침입자가 아니라 단지 임포트 에러를 맞이할 뿐이다.
이전 글 : Programming C# - 4부
다음 글 : SMTP를 이용해서 이메일 전송하기
최신 콘텐츠