CVE-2022-28347: Potential SQL injection in Django QuerySet `explain()` Analysis
2022. 7. 21. 15:35
https://github.com/advisories/GHSA-w24h-v9qh-8gxj
CVE-2022-28347 - GitHub Advisory Database
SQL Injection in Django
github.com
이 취약점은 PostgreSQL 환경에서 Django QuerySet의 explain 기능을 수행할 때 발생 가능한 SQL Injection 취약점이다. QuerySet 오브젝트의 explain() 메소드를 수행하면 EXPLAIN 명령어를 사용할 수 있는데, MySQL과 PostgreSQL에서는 특별히 EXPLAIN 명령어에 옵션을 지정할 수 있다. 이 기능을 구현한 explain() 메소드에서 발생했던 SQL Injection 보안 취약점(CVE-2022-28347)을 취약점을 분석해보고자 한다.
- QuerySet QuerySet 오브젝트의 explain() 메소드 수행하면 self.query.explain() 메소드를 수행한다. 이 self.query attribute는 django.db.models.sql.query.Query 클래스로, 결국 djagno.db.models.sql.query.Query.explain() 메소드를 수행한다.
- Query Query클래스의 explain() 메소드는 get_compiler() 메소드를 통해 compiler를 가져오고 사용하는 DB에 맞추어 django.db.models.sql.compiler.SQLCompiler를 상속한 클래스의 explain_query() 메소드를 실행시켜준다.
- SQLCompiler SQLCompiler 클래스 내부의 explain_query() 메소드에서는 동일 클래스의 execute_sql()를 실행한다. 실제로 SQL Query구문을 실행하는 메소드이며, 이 메소드 안에서는 explain_info를 검사하는데 이것은 2번 과정에서 Query 클래스의 explain() 메소드에서 namedtuple()로 설정된 값이다.
- SQLCompiler execute_sql() 메소드에서는 Query 오브젝트에 설정된 explain_info attribute가 있다면, 동일 클래스의 explain_query_prefix()를 실행한다.
- BaseDatabaseOperatios의 explain_query_prefix() 메소드는 크게 하는 역할이 없다. 인자로 전달된 format, options의 값을 검사하는데 format의 경우 기본적으로 설정되어 있지 않아 format 값을 지정할 수 없고, options는 그냥 값이 존재한다면 ValueError를 raise한다.
- postgresql의 DatabaseOptions는 explain_query_prefix() 메소드에 유의미한 코드가 있다. (아래 참고) 우선 format 값이 지정된 format인지 확인하고, options를 설정한다. 이때 options로 넘겨진 key 값을 검사하지 않고 넘기기 때문에 options에 SQL 구문을 넣으면 SQL Injection이 가능하다.
![](https://blog.kakaocdn.net/dn/b3nBbf/btrHTIJzo5X/EBkYIFo0KYdekdb0byiSsk/img.png)
'write-ups' 카테고리의 다른 글
CVE-2022-34265: Potential SQL injection via `Trunc(kind)` and `Extract(lookup_name)` arguments (0) | 2022.07.15 |
---|---|
HackTheBox Heist write-up (0) | 2021.05.10 |
HackTheBox LoveTok write-up (0) | 2021.04.19 |
HackTheBox baby website rick write-up (0) | 2021.04.15 |
HackTheBox baby breaking grad write-up (0) | 2021.04.15 |