[시큐어코딩 가이드] 2-1-8. 부적절한 XML 외부 개체 참조

부적절한 XML 외부 개체 참조

정의

  • XML 문서에는 DTD(Document Type Definition)를 포함할 수 있으며, DTD는 XML 엔티티(entitiy)를 정의
  • 서버에서 XML 외부 엔티티를 처리할 수 있도록 설정된 경우에 발생
  • 취약한 XML parser가 외부값을 참조하는 XML을 처리할 때, 공격자가 삽입한 공격 구문이 동작되어 서버 파일 접근, 불필요한 자원 사용, 인증 우회, 정보 노출 등이 발생

 

안전한 코딩기법

  • 로컬 정적 DTD를 사용하도록 설정하고, 외부에서 전송된 XML 문서에 포함된 DTD를 완전하게 비활성화해야 한다. 비활성화를 할 수 없는 경우에는 외부 엔티티 및 외부 문서 유형 선언을 각 파서에 맞는 고유한 방식으로 비활성화 한다.
  • 외부 라이브러리를 사용할 경우 기본적으로 외부 엔티티에 대한 구문 분석 기능을 제공하는지 확인하고, 제공이 되는 경우 해당 기능을 비활성화 할 수 있는 방법을 확인해 외부 엔티티 구문 분석 기능을 비활성화 한다.

 

코드예제

다음은 XML 소스를 읽어 분석하는 코드입니다. 공격자는 XML 외부 엔티티를 참조하는 xxe.xml 데이터를 전송하고, 이를 파싱할 때 /etc/passwd 파일을 참조할 수 있습니다. 만약 sax 패키지를 사용해 XML을 파싱할 경우, 외부 엔티티를 처리하는 방식의 옵션(feature_external_ges)을 False로 설정해야 합니다.

from .models import comments

def get_xml(request):
    if request.method == "GET":
        data = comments.objects.all()
        com = data[0].comment
        return render(request, 'xml_view.html', {'com': com})

    elif request.method == "POST":
        parser = make_parser()
        parser.setFeature(feature_external_ges, True) #안전하지 않은 코드
        #parser.setFeature(feature_external_ges, Fasle) #안전한 코드
        doc = parseString(request.body.decode('utf-8'), parser=parser)
        for event, node in doc:
            if event == START_ELEMENT and node.tagName == "foo":
                doc.expandNode(node)
                text = node.toxml()
                comments.objects.filter(id=1).update(comment=text)
        return render(request, 'xml_view.html')

 

 

 

입력데이터 검증 및 표현/부적절한 XML 외부 개체 참조

[참고문헌] Python 시큐어코딩 가이드(2022) / KISA(한국인터넷진흥원)