CVE-2025-2945에 대해서 알아봅시다.
What is pgAdmin4
pgAdmin4는 postgresql을 쉽게 관리할 수 있도록 도와주는 도구입니다.
pgAdmin4는 Python, ReactJs, Javascript를 사용하여 pgAdmin을 만들었습니다.
Electron으로 만들어진 Desktop 런타임을 통해 개별 사용자가 단독으로 실행하거나, Flask 기반으로 만들어진 웹 서비스를 통해 1명 이상의 사용자가 웹 브라우저를 통해 사용할 수 있습니다.
해당 취약점은 Flask 기반으로 만들어진 웹 서비스에서 발생했습니다.
CVE-2025-2945
PgAdmin4의 Query Tool 및 Cloud Deployment 모듈에서 발견된 원격 코드 실행 취약점으로, Python eval() 함수의 안전하지 않은 사용으로 인해 발생합니다.
영향 받는 엔드포인트
- Query Tool (
/sqleditor/query_tool/download/<int:trans_id>
) - Cloud Deployment modules (
/cloud/deploy
)
공격 전제 조건
- PgAdmin4 버전 9.2 미만
- 웹 서비스 형태로 실행되는 PgAdmin4 환경
- 인증된 사용자(로그인 가능)
- 엔드포인트에 POST 요청이 가능해야함
취약한 코드
- 마지막 줄을 보면 eval 함수를 통해 사용자의 입력 값을 실행하고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# https://github.com/pgadmin-org/pgadmin4/blob/REL-9_1/web/pgadmin/tools/sqleditor/__init__.py#L2124-L2160
@blueprint.route(
'/query_tool/download/<int:trans_id>',
methods=["POST"],
endpoint='query_tool_download'
)
@pga_login_required
def start_query_download_tool(trans_id):
(status, error_msg, sync_conn, trans_obj,
session_obj) = check_transaction_status(trans_id)
if not status or sync_conn is None or trans_obj is None or \
session_obj is None:
return internal_server_error(
errormsg=TRANSACTION_STATUS_CHECK_FAILED
)
data = request.values if request.values else request.get_json(silent=True)
if data is None:
return make_json_response(
status=410,
success=0,
errormsg=gettext(
"Could not find the required parameter (query)."
)
)
try:
sql = None
query_commited = data.get('query_commited', False)
# Iterate through CombinedMultiDict to find query.
for key, value in data.items():
if key == 'query':
sql = value
if key == 'query_commited':
query_commited = (
eval(value) if isinstance(value, str) else value # vuln code
)
취약점 검증
1
2
3
4
5
1. python -m venv pgadmin //파이썬 가상환경
2. cd pgadmin/Script
3. activate // 가상환경 실행
4. pip install pgadmin4-9.1-py3-none-any.whl //PgAdmin4 공식 홈페이지 다운로드
5. pgadmin4 //서비스 실행
[Result]
1
2
3
4
(pgadmin) C:\Users\AKM\Downloads\pgadmin\Scripts>pgadmin4
Starting pgAdmin 4. Please navigate to http://127.0.0.1:5050 in your browser.
* Serving Flask app 'pgadmin'
* Debug mode: off
Exploit
- postgres에 연결하여
trans_id
를 얻어야합니다.- 쿼리 결과를 다운로드를 하여 trans_id를 획득합니다.
대응 방안
- PgAdmin4를 9.2 버전 이상으로 업데이트
- 9.2 미만 버전에 CVE-2025-2946(XSS) 추가 취약점이 발견되어 9.2버전에서 해소되었음
- 9.2버전에서는 eval()을 안쓰도록 수정되었음
Conclusion
eval() 함수는 절때 쓰지 말아야 합니다….