- 개요
Django는 Python으로 개발할 수 있는 웹 어플리케이션 프레임워크로 postgresql을 database로
사용한 Django 서버에서 JSONField와 HStoreField를 사용할 때 filter 함수를 통한
SQLinjection취약점이 발생합니다.
- 취약한 버전
Django 2.2 ~ 2.2.3
Django 2.1 ~ 2.1.10
Django 1.11 ~ 1.11.22
- 취약점 설명 및 분석
먼저 취약한 코드의 패치 내역은 다음과 같습니다.
해당 취약점이 발생하기 위한 전제 조건은 Column의 Type이 Jsonb, hstore여야만 합니다.
Jsonb는 아래와 같은 포맷을 통해 데이터를 찾습니다.
이 때 생성되는 검색 query는 다음과 같습니다.
data__nickname 이 분리되어 (“table”.”data” -> ‘nickname’)의 형태를 만들게 됩니다.
위의 패치 내역을 보면 “(%s %s %s)” % (lhs, self.operator, lookup) 이런 형태로 반환하게 되는데
lhs는 “table”.”data”, self.operator는 -> , lookup은 nickname이라는 것을 알 수 있습니다.
위의 코드에서는 self.key_name을 lookup에 넣는데 필터링을 거치지 않고 넣는 것으로 보입니다.
아래와 같이 ‘(single quote) 를 lookup에 삽입했을 시 syntax error가 나오게 됩니다.
‘ 와 ) 을 이용해 query를 닫아주고 or 구문과 주석처리를 통해 SQLinjection이 발생하는 것을
확인할 수 있습니다. (테스트를 위해 입력한 query가 보이도록 설정했습니다.)
Mysql과 마찬가지로 union을 이용해 database, table, column, data를 추출할 수 있습니다.
Hstore도 jsonb와 마찬가기로 아래와 같은 형태로 데이터를 검색합니다.
그렇기에 jsonb와 똑같은 형태로 SQLinjection이 발생합니다.
Jsonb와 hstore의 패치 내역은 다음과 같습니다.
기존에는 (“A”.”B” -> ‘c’)의 형태로 반환했다면 패치된 후엔 (“A”.”B” -> %s) ,
[self.key_name] + params 의 형태로 반환되게 됩니다. Jsp의 prepared statement와 비슷한
형식으로 패치가 되어 패치된 최신 버전에서는 SQLinjection이 발생하지 않습니다.
- 위협요소
공격자에 의해 database의 중요 정보가 탈취당할 위협이 존재합니다.
- 대응방안
1) Django 최신 버전 업데이트