🔍 CVE-2026-12047

3.5
CVSS Score
LOW
2026-06-19
2026-06-29 15:18
✅ 완료

🇰🇷 한글 설명

pgAdmin 4의 클라우드 배포 모듈에서 SDK 예외 메시지가 HTML 인코딩 없이 JSON 응답에 포함되어 발생하는 HTML 인젝션 취약점입니다. 공격자가 조작된 자격 증명을 입력하면 클라우드 위저드 프론트엔드가 이를 HTML로 렌더링하여 악성 iframe을 실행하거나 페이지를 리다이렉트할 수 있습니다.

💡 쉬운 설명

클라우드 설정을 도와주는 기능에서 오류 메시지를 처리할 때 보안 검사를 하지 않아 발생하는 문제입니다. 공격자가 특수하게 만든 코드를 입력하면 관리자의 화면이 이상한 사이트로 바뀌거나 해킹될 위험이 있습니다.

🇺🇸 원문 (English)

HTML injection in pgAdmin 4's cloud deployment module. The verify_credentials, deploy, regions, and update-server endpoints under /rds/, /azure/, /google/, and the top-level /cloud/ blueprint propagated AWS / Azure / Google SDK exception text — and the related file-resolution and database-commit exception text — into the JSON response body (the info and errormsg fields) without HTML-encoding. The Cloud Wizard frontend rendered these strings through html-react-parser, so an attacker-influenced exception message embedded structural HTML directly into the wizard's DOM. The reported entry point is /rds/verify_credentials/. An authenticated pgAdmin user submits a crafted access_key whose value contains an <iframe/src=...> payload; AWS STS rejects the credential with an IncompleteSignature exception whose text quotes the access_key verbatim; the pgAdmin backend forwards that text into the JSON info field; the Cloud Wizard's FormFooterMessage parses it as HTML. The browser fetches the iframe's src from an attacker-controlled host, and JavaScript executing inside the cross-origin iframe writes to parent.location, redirecting the victim's pgAdmin tab. Because the injection renders inside pgAdmin's own interface, X-Frame-Options and Content-Security-Policy frame-ancestors do not mitigate it. Baseline impact is self-targeted (the same user who supplied the payload sees the injection); escalation against other authenticated users requires an additional cross-site request-forgery primitive capable of submitting the malformed credential request with a valid X-pgA-CSRFToken in the victim's browser context. The same unsanitised-error-into-JSON pattern was present across multiple sibling endpoints — Azure's check_cluster_name_availability, every Google endpoint that surfaces SDK errors (verification_ack, projects, regions, instance_types, database_versions, the verify_credentials path-resolution branches), the central /deploy endpoint that bubbles str(e) from deploy_on_rds / deploy_on_azure / deploy_on_google, and update_cloud_server which surfaces the str(e) from a failing db.session.commit — all of which are now covered. Fix HTML-escapes every external/SDK exception string at the endpoint sink via a new shared sanitize_external_text helper (HTML escape with control-character strip), promoted out of the psycopg3 driver into web/pgadmin/utils/text_sanitize.py. The Cloud Wizard frontend additionally renders its FormFooterMessage in plain-text mode for backend-derived strings, so the value is never parsed as HTML even if a future sink forgets the escape. This issue affects pgAdmin 4: from 6.6 before 9.16.

📍 영향받는 시스템

pgAdmin 4: 6.6 버전부터 9.16 미만 버전

⚔️ 공격 벡터

인증된 사용자가 조작된 access_key를 포함한 요청을 /rds/verify_credentials/ 등의 엔드포인트로 전송

🛡️ 대응 방법

pgAdmin 4를 9.16 이상의 최신 버전으로 업데이트하거나, 외부 SDK 예외 메시지에 대해 HTML 이스케이프 처리를 적용

🔧 검증 코드

출력된 버전이 6.6 이상 9.16 미만인지 확인하여 취약 여부를 판단합니다.

Shell / Script
pip show pgadmin4 2>/dev/null | grep -E 'Version'

📊 CVSS Vector String

CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:N

💻 영향받는 소프트웨어

Azure