내 데이터베이스 하나 가졌을 뿐인데, PostgreSQL 서버 코드 실행까지 갔다
내 데이터베이스 하나 가졌을 뿐인데, PostgreSQL 서버 코드 실행까지 갔다
CVE · 클라우드·쿠버네티스 · 권한상승→원격코드실행(RCE) · CVE-2026-78155 [표준]
StackGres 오퍼레이터의 이번 사례는 처음 보면 “소유자 권한이 관리자 권한으로 샜다”는 흔한 인가 결함처럼 읽힙니다. 그런데 실제로는 훨씬 구체적이고 훨씬 심각합니다 — 자기 데이터베이스 하나를 소유한 저권한 테넌트가, 메트릭 수집기가 슈퍼유저 권한으로 여는 PostgreSQL 세션의 검색 경로(search_path)를 조작해, 주(primary) PostgreSQL 파드 안에서 원격 코드를 실행할 수 있습니다. “관리자 권한 획득”은 이 취약점이 도달하는 여러 결과 중 하나일 뿐이고, 진짜 바닥은 서버 프로세스 탈취입니다.
개요
CVE-2026-78155는 StackGres(쿠버네티스 위에서 PostgreSQL 클러스터를 운영하는 오픈소스 오퍼레이터, 벤더 OnGres) 의 1.18.8 이하 전 버전(기본 활성화된 메트릭 익스포터 포함)에 영향을 주는 취약점입니다. 벤더 GitLab work item #3177에 따르면, 근본원인은 메트릭 익스포터가 dblink를 통해 PostgreSQL 슈퍼유저 권한으로 세션을 여는데, 그 세션이 스키마를 완전히 한정(qualify)하지 않은 함수·테이블 호출을 쓰고 search_path를 명시적으로 고정(SET search_path)하지 않는다는 데 있습니다. 자기 데이터베이스를 소유한 테넌트는 자기 스키마에 같은 이름의 객체를 만들어 두는 방식으로 이 세션이 참조하는 시스템 카탈로그 객체를 가로채고(shadowing), search_path를 조작해 슈퍼유저 세션이 자신이 심어 둔 객체를 대신 실행하게 만듭니다. 이 경로 끝에서 COPY ... TO PROGRAM 같은 PostgreSQL 슈퍼유저 전용 기능에 도달하면, 주 PostgreSQL 파드 안에서 임의 명령 실행이 성립합니다.
- 취약 제품: StackGres 오퍼레이터 — 1.x부터 1.18.8까지(기본 메트릭 익스포터 포함 전 릴리스), 패치 버전 1.19.0. (CVE API affected/solution 확정)
- 취약점 유형: PostgreSQL 신뢰할 수 없는 검색 경로(Untrusted Search Path) 이용 — CWE-426. 카탈로그 객체 가로채기(schema/catalog shadowing) + search_path 미고정 조합으로, 슈퍼유저 세션이 공격자가 심은 객체를 실행하게 만드는 결함입니다.
- 핵심 메커니즘: 메트릭 익스포터의
dblink슈퍼유저 세션 → 미한정(unqualified) 객체 참조 +search_path고정 부재 → 테넌트가 자기 스키마로 카탈로그 객체를 가로챔 →COPY ... TO PROGRAM등으로 원격 코드 실행. - 전제: 유효한 저권한 테넌트 계정 + 자기 소유 데이터베이스가 필요합니다(무인증 원격 공격이 아님) — CVSS
PR:L(낮은 권한 필요)로 확정. - CVSS 3.1: 9.9(CRITICAL), 벡터
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H— CVE API metrics 확정.
한 줄 요약: “이 데이터베이스는 내 것”이라는 정당한 소유권이, 슈퍼유저가 대신 열어 준 세션의 검색 경로를 흔들 수 있는 힘으로 이어졌고, 그 끝에 서버 프로세스 코드 실행이 있었습니다.
기술 배경 — PostgreSQL의 search_path는 신뢰 경계다
PostgreSQL에서 SELECT foo()처럼 스키마를 적지 않고 객체 이름만 쓰면, 서버는 search_path에 나열된 스키마를 순서대로 뒤져 가장 먼저 찾은 foo를 실행합니다. 이 기능은 편의를 위한 것이지만, 동시에 **“이름만으로 부르면, 그 이름을 먼저 등록한 쪽이 이긴다”**는 함정을 만듭니다.
일반 사용자가 자기 스키마에 시스템 함수·테이블과 같은 이름의 객체를 만들어 두고, search_path가 그 스키마를 시스템 스키마보다 먼저 뒤지게 만들면, 원래 시스템 객체를 부르려던 호출이 사용자가 심어 둔 가짜 객체로 슬쩍 넘어갑니다. 이를 **카탈로그/스키마 가로채기(catalog shadowing)**라 부릅니다. PostgreSQL 공식 문서가 오래전부터 “함수를 정의하거나 확장을 설치할 때는 search_path를 명시적으로 고정하라”고 권고하는 이유가 바로 이것입니다.
여기에 dblink(다른 PostgreSQL 세션에 연결해 쿼리를 실행하는 확장)가 끼면 위험이 한 단계 커집니다. 어떤 백그라운드 작업(예: 메트릭 수집)이 dblink로 슈퍼유저 권한 세션을 열어 놓고, 그 세션 안에서 스키마를 명시하지 않은 채 함수·테이블을 호출한다면 — 저권한 사용자가 만들어 둔 가짜 객체가 슈퍼유저 권한으로 실행될 길이 열립니다. 자기 스키마를 마음대로 쓸 수 있는 것은 정당한 소유자 권한이지만, 그 스키마가 슈퍼유저 세션의 search_path에 끼어들 수 있다면 이야기가 달라집니다.
CVE 분석 요약 — 소유권이 슈퍼유저 세션의 이름 해석을 흔드는 지점
벤더 work item #3177에 근거해 정리하면, 결함의 연쇄는 다음과 같습니다.
- StackGres 메트릭 익스포터가
dblink로 PostgreSQL 슈퍼유저 세션을 엽니다. 클러스터 전체의 지표를 모으기 위해, 각 테넌트 데이터베이스에 슈퍼유저 권한으로 접속해 조회를 수행합니다. - 이 세션이 스키마를 완전히 한정하지 않은 호출을 쓰고,
search_path를 명시적으로 고정하지 않습니다. 즉 어떤 스키마를 먼저 뒤질지가 해당 데이터베이스의 기본search_path설정에 좌우됩니다. - 자기 데이터베이스를 소유한 테넌트는 이
search_path와 자기 스키마 안의 객체 이름을 자유롭게 조작할 수 있는 정당한 권한을 가지고 있습니다. 소유자는 이 권한을 이용해, 슈퍼유저 세션이 호출할 이름과 같은 이름의 함수/테이블을 자기 스키마에 만들어 둡니다. - 슈퍼유저 세션이 다음 조회를 수행할 때, 미한정 호출이 시스템 객체 대신 테넌트가 심어 둔 객체로 해석됩니다. 이 시점부터 테넌트가 만든 코드가 슈퍼유저 권한으로 실행됩니다.
- 슈퍼유저 권한을 손에 쥔 상태에서,
COPY ... TO PROGRAM처럼 슈퍼유저에게만 허용된 PostgreSQL 기능에 도달하면 임의 명령 실행이 성립합니다. 이것이 work item #3177이 명시하는 주 PostgreSQL 파드 내 원격 코드 실행입니다.
즉 원인은 “인가 검사가 어디서 빠졌나”가 아니라 **“슈퍼유저 권한으로 실행되는 세션이, 저권한 사용자가 통제 가능한 이름 해석 규칙(search_path)에 자신의 신뢰를 걸었다”**는 것입니다. 소유권 자체는 결함이 아닙니다. 문제는 그 소유권이 미치는 범위(자기 스키마)와, 슈퍼유저 세션이 실수로 그 범위를 자기 신뢰 경계 안으로 끌어들인 것입니다.
# 개념용 단순화, 실제 페이로드/원본 코드 아님 (무해화 — 완성형 명령·구체 함수명은 싣지 않습니다)
[메트릭 익스포터, 슈퍼유저 dblink 세션]
search_path 고정 없이 미한정 이름으로 객체 호출
│
▼
[테넌트 소유 스키마] ← 소유자가 같은 이름으로 만들어 둔 객체가 여기 있음
│ (search_path 순서상 시스템 스키마보다 먼저 뒤져짐)
▼
슈퍼유저 세션이 "시스템 객체"인 줄 알고 테넌트 객체를 실행
│
▼
슈퍼유저 권한 획득 → 슈퍼유저 전용 기능 경로 → 서버 프로세스에서 코드 실행
개념용 단순화 — 실제 스키마명·함수명·명령은 옮기지 않았습니다. 완성된 익스플로잇/페이로드가 아닙니다.
공격 시나리오 · 영향도 + 대응방안
공격 시나리오(개념, 완성형 명령·페이로드 없음).
- 공격자가 정당한 저권한 테넌트 계정으로 로그인하고, 플랫폼에서 자기 데이터베이스를 하나 만들어 소유자 지위를 확보합니다.
- 자기 스키마 안에, 메트릭 익스포터의 슈퍼유저 세션이 미한정으로 호출할 것으로 예상되는 이름의 객체를 만들어 둡니다.
- 메트릭 수집 주기가 돌면서 슈퍼유저 세션이 그 객체를 “시스템 객체”로 착각해 호출하고, 테넌트가 심은 코드가 슈퍼유저 권한으로 실행됩니다.
- 슈퍼유저 전용 기능을 통해, 그 코드가 주 PostgreSQL 파드 안에서 임의 명령을 실행합니다.
영향도. 벤더가 확정한 범위는 **주 PostgreSQL 파드 내 원격 코드 실행(RCE)**입니다 — “관리자 권한 획득”에서 멈추지 않습니다. 이 파드에서 코드 실행이 성립하면, 그 파드가 접근 가능한 다른 테넌트의 데이터베이스·클러스터 설정·자격증명, 나아가 쿠버네티스 클러스터 내 인접 자원까지 파급될 수 있습니다(합리적으로 예상되는 후속 영향 — 벤더 문서가 별도로 확정한 범위는 아닙니다). 멀티테넌트로 운영되는 관리형 Postgres 환경일수록 테넌트 간 격리 붕괴의 파급이 큽니다. 다만 이 취약점은 유효한 저권한 계정과 데이터베이스 소유를 전제하므로(CVSS PR:L), 무인증 외부 공격과는 전제 조건이 다릅니다.
대응방안.
- 근본 — StackGres 1.19.0 이상으로 즉시 업데이트. 벤더가 확정한 패치 버전입니다. 1.18.8 이하(기본 메트릭 익스포터 포함) 전 릴리스가 영향을 받으므로, 메트릭 익스포터를 쓰지 않는 배포라도 버전을 확인해야 합니다.
- 완화(즉시 업데이트가 어려울 때).
- 메트릭 익스포터를 비활성화하거나, 최소한 슈퍼유저가 아닌 제한된 권한으로 실행되도록 구성을 재검토합니다.
- 저권한 테넌트의 데이터베이스 소유 권한 범위를 감사해, 테넌트가 임의로 만들 수 있는 객체가 슈퍼유저 세션의 이름 해석에 영향을 줄 수 있는 경로가 있는지 점검합니다.
- 자체 운영 중인 PostgreSQL 워크로드에서도 슈퍼유저·확장 권한으로 도는 백그라운드 세션은 반드시
search_path를 명시적으로 고정하는 일반 원칙을 적용합니다(SET search_path = pg_catalog, ...등).
- 탐지 관점. 슈퍼유저 권한으로 도는
dblink/백그라운드 세션이 예상 밖의 스키마에서 객체를 해석하는 로그, 저권한 계정이 시스템 함수·테이블과 동일한 이름의 객체를 자기 스키마에 생성하는 이벤트,COPY ... TO PROGRAM류의 슈퍼유저 전용 기능 호출 로그를 감사 대상으로 둡니다.
결론
StackGres의 이번 사례는 “소유자와 관리자를 헷갈렸다”는 표면적 서사보다 훨씬 구체적인 교훈을 줍니다. 슈퍼유저 권한으로 도는 세션이 저권한 사용자가 통제 가능한 이름 해석 규칙(search_path)에 의존하면, 소유권이라는 정당한 권한 하나만으로 서버 프로세스 코드 실행까지 갈 수 있습니다.
이 부류의 버그가 특히 위험한 이유는, 손상되는 것이 애플리케이션 코드가 아니라 데이터베이스 엔진 자체의 신뢰 모델이기 때문입니다. dblink·확장·자동화 스크립트가 슈퍼유저 권한으로 도는 지점마다, “이 세션이 부르는 이름이 정말 내가 의도한 객체인가”를 확인해야 합니다 — search_path를 명시적으로 고정하는 한 줄이 그 확인의 전부입니다. 이는 우리가 다른 글에서 다룬 신뢰 경계 결함들과 뿌리가 같습니다: 바깥(또는 저권한 쪽)이 통제할 수 있는 값에 특권 프로세스가 이름/판정을 맡긴 것. 그래서 우리는 이 CVE 하나가 아니라 “특권으로 도는 코드가 신뢰 경계 밖의 이름 해석에 기대고 있지 않은가”라는 방법을 남깁니다.
(이 CVE의 심층 분석판은 아직 없습니다. 소스 대조·패치 diff까지 파는 심층판으로 승급하면 여기에 링크됩니다.)
References / 참고자료
- GitLab(OnGres) work item #3177 — 이 글이 재구성한 1차출처. 근본원인(search_path/카탈로그 가로채기)·영향(주 PostgreSQL 파드 RCE)·영향 버전(≤1.18.8)·패치 버전(1.19.0) 근거. 발견자 크레딧: Cipher(Causal Security). https://gitlab.com/ongresinc/stackgres/-/work_items/3177
- MITRE CVE API — CVE-2026-78155 공식 레코드. CVSS 3.1 9.9 (
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H), CWE-426(Untrusted Search Path) 근거. https://cveawg.mitre.org/api/cve/CVE-2026-78155 - PostgreSQL 공식 문서, “Writing SECURITY DEFINER Functions Safely” —
search_path고정 권고의 일반 원리 배경(개념 인용용). - Kubernetes 공식 문서, “Operator pattern” — 오퍼레이터 관리 계층에 관한 표준 배경.
이 글은 위 1차출처(GitLab work item #3177·MITRE CVE API)를 우리 관점에서 다시 쓰고 논평을 더한 것입니다. 특정 문장·코드를 그대로 옮기지 않았으며, 완성된 익스플로잇/페이로드는 싣지 않았습니다. 도식은 개념 설명용입니다. 이 초안은 RN-11 독립 팩트체크(2026-08-31)를 거쳐 근본원인 서사가 전면 정정된 버전입니다.