Supabase 셀프호스팅 CVE 탐지부터 패치까지 — GoTrue 인증 우회, Docker Compose Path Traversal, Trivy 스캔 예시
저도 처음엔 "어차피 내부망에서만 쓰는데 괜찮겠지" 하고 6개 컨테이너를 초기 설치 상태 그대로 수개월 돌린 적이 있었습니다. 그러다 RLS 미설정으로 170개 이상의 Supabase 앱이 외부에 데이터를 노출한 사례를 접했을 때, 내부망이라는 믿음이 얼마나 허술한 방어선인지 실감했습니다. Supabase Cloud를 쓴다면 Supabase 팀이 자동으로 패치해주지만, Docker Compose로 직접 운영하는 순간 PostgreSQL, Kong, GoTrue, PostgREST, Realtime, Studio — 이 여섯 개 이상의 이미지를 모두 직접 추적해야 합니다.
이 글을 읽고 나면 현재 운영 중인 스택에서 30분 안에 CVE를 스캔하고 우선순위를 매길 수 있습니다. 2025~2026년 사이에 공개된 굵직한 CVE들을 중심으로, 취약점 탐지부터 실제 패치 적용, 재발 방지 체계 구성까지의 흐름을 Docker Compose로 Supabase를 직접 운영하는 분들에게 맞춰 정리했습니다.
Auth 우회부터 docker compose ps 한 줄로 호스트 파일시스템을 건드릴 수 있는 Path Traversal까지 — 생각보다 가까이에 있는 취약점들입니다.
핵심 개념
CVE, CVSS, EPSS, KEV — 우선순위를 가르는 네 가지 지표
보안 이야기를 하다 보면 이 용어들이 뒤섞여 나오는데, 한 번만 정리해두면 CVE 리포트를 읽을 때 훨씬 수월합니다.
CVE (Common Vulnerabilities and Exposures): 공개된 보안 취약점에 부여되는 고유 식별자.
CVE-연도-번호형식. CVSS 점수(0~10)로 심각도를 나타내며, 7.0 이상은 High, 9.0 이상은 Critical.
CVSS (Common Vulnerability Scoring System): 취약점 자체의 특성(네트워크 접근성, 공격 복잡도, 사용자 인터랙션 필요 여부 등)을 종합한 점수. "얼마나 나쁜 취약점인가"를 측정하지만, "지금 당장 공격받을 가능성"은 반영하지 않습니다.
EPSS (Exploit Prediction Scoring System): CVE가 실제로 익스플로잇될 가능성을 0~1 확률로 예측하는 지표. CVSS가 높아도 EPSS가 낮으면 즉각 위협 가능성은 낮고, 반대로 CVSS가 낮아도 EPSS가 높으면 빠른 대응이 필요합니다.
KEV (Known Exploited Vulnerabilities): CISA가 실제 야생(in the wild)에서 익스플로잇이 확인된 CVE를 등록하는 목록. KEV 등재 여부는 CVSS 점수와 무관하게 최우선 패치 신호로 봐야 합니다.
이 네 가지를 조합해서 "CVSS는 낮지만 KEV에 등재됐다"거나 "CVSS는 높지만 EPSS가 0.001이다"를 읽어낼 수 있어야, 수십 개의 CVE 중에서 지금 당장 봐야 할 것을 골라낼 수 있습니다.
Supabase Docker 스택의 CVE 발생 레이어
취약점은 크게 세 레이어에서 발생합니다.
| 레이어 | 대상 | 예시 |
|---|---|---|
| Supabase 애플리케이션 | GoTrue(Auth), auth-js 등 | CVE-2026-31813 Auth Bypass |
| Docker/컨테이너 | Docker Compose, Docker Engine | CVE-2025-62725 Path Traversal |
| 베이스 이미지 OS | Debian, Alpine 패키지 | libssl, glibc 등 시스템 라이브러리 |
실무에서 자주 맞닥뜨리는 상황이 있는데, 애플리케이션 이미지는 최신인데 베이스 이미지의 openssl이 구버전인 경우입니다. 이 세 레이어를 동시에 모니터링하지 않으면 이런 사각지대가 생깁니다.
대응의 기본 흐름
복잡해 보이지만 기본 흐름은 단순합니다.
- 스캔: Trivy나 Grype로 현재 이미지에 어떤 CVE가 있는지 파악
- 우선순위 평가: CVSS + EPSS + KEV 등재 여부를 조합해 판단
- 패치 적용: 이미지 태그 업데이트 또는 임시 완화 조치
- 검증: 패치 후 재스캔으로 취약점 해소 확인
실전 적용
예시 1: CVE-2026-31813 — GoTrue Auth 우회 긴급 대응
Apple 또는 Azure OIDC 로그인을 쓰고 있고 GoTrue 버전이 v2.185.0 미만인 경우에 해당합니다. 악의적으로 조작된 ID 토큰으로 임의 사용자 세션을 발급받을 수 있는 인증 우회 취약점입니다.
CVSS가 4.8(Medium)이라 방심하기 쉬운데, 이 점수가 낮은 데는 이유가 있습니다. CVSS는 공격 조건을 종합 평가하는데, 이 취약점은 Apple이나 Azure OIDC 프로바이더가 활성화된 특정 설정에서만 발현됩니다. "누구에게나 열려 있는" 취약점이 아니라 "특정 설정이 있어야 열리는" 취약점이라 점수가 낮게 책정된 것입니다. 그래서 CVSS 점수보다 "우리 환경이 조건에 해당하는가"를 먼저 확인하는 게 더 중요합니다. 해당 설정이 있다면 즉각 패치가 낫습니다.
# GoTrue 이미지만 최신 버전으로 교체
docker pull supabase/gotrue:v2.185.0
# 다른 서비스는 그대로 두고 auth만 재시작
docker compose up -d --no-deps auth
# 버전 확인 (이미지 메타데이터 대신 바이너리 직접 실행)
docker run --rm supabase/gotrue:v2.185.0 --version즉각 패치가 어려운 상황이라면 네트워크 레벨에서 임시 완화를 적용해볼 수 있습니다. iptables 규칙 순서에 주의가 필요합니다 — DROP보다 ACCEPT가 반드시 앞에 와야 합니다.
# 내부망(10.0.0.0/8)은 허용, 나머지는 차단
# -I로 체인 상단에 ACCEPT를 먼저 삽입하고, -A로 DROP을 끝에 추가
iptables -I INPUT -p tcp --dport 9999 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 9999 -j DROPACCEPT와 DROP의 순서가 뒤바뀌면 내부망도 차단되는 상황이 생깁니다. 임시 완화와 함께 Supabase 대시보드의 Authentication 설정에서 Apple, Azure 프로바이더를 비활성화해두면 추가적인 방어선이 됩니다.
예시 2: CVE-2025-62725 — Docker Compose Path Traversal 패치
저희 팀에서 이 CVE를 처음 접한 건 일상적인 docker compose config 실행 중이었습니다. Docker Compose v2.40.2 이전 버전에서 OCI 아티팩트 레이어 어노테이션의 경로 검증이 미흡해 호스트 파일시스템 임의 위치에 파일을 쓸 수 있는 취약점(CVSS 8.9, High)입니다.
특히 위험한 이유는 docker compose ps나 docker compose config 같은 읽기 전용 명령 실행 중에도 트리거될 수 있다는 점입니다. 악성 OCI 이미지를 참조하는 docker-compose.yml 파일만 있어도 위험한 상황이 만들어집니다.
# 현재 Docker Compose 버전 확인
docker compose version
# Docker Desktop 사용자: Desktop 업데이트로 함께 해결됩니다
# Linux에서 독립 설치한 경우: 아키텍처 자동 감지 후 업데이트
ARCH=$(uname -m)
curl -SL "https://github.com/docker/compose/releases/download/v2.40.2/docker-compose-linux-${ARCH}" \
-o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# 업데이트 후 버전 재확인
docker compose version
# Docker Compose version v2.40.2 이상이어야 합니다uname -m으로 아키텍처를 동적으로 감지하면 x86_64(Intel/AMD)와 aarch64(ARM, M1/M2 Mac, Graviton EC2) 모두에서 동일하게 쓸 수 있습니다.
예시 3: Trivy로 Supabase 이미지 스캔하기
컨테이너 스캐너 중 Trivy가 가장 널리 쓰이는데, 한 가지 꼭 짚고 넘어가야 할 사건이 있습니다. 2026년 3월 Docker Hub의 Trivy 이미지(0.69.4~0.69.6, latest 태그)가 공급망 침해 사고를 겪었습니다. CI/CD에서 trivy:latest를 그냥 쓰고 있다면 검토가 필요합니다.
# digest로 핀닝해서 사용 (latest 태그는 피하는 게 좋습니다)
# docker.io/aquasec/trivy@sha256:<검증된_다이제스트>
# 현재 실행 중인 postgres 이미지 태그 확인 방법
docker inspect --format '{{index .RepoTags 0}}' $(docker ps -q -f name=supabase_db)
# 또는 .env 파일에서 버전 읽기
POSTGRES_VERSION=$(grep POSTGRES_IMAGE .env | cut -d= -f2 | cut -d: -f2)
# Supabase postgres 이미지 스캔
trivy image supabase/postgres:15.6.1.143
# CI/CD 통합: CRITICAL, HIGH만 빌드 실패 처리
trivy image \
--severity CRITICAL,HIGH \
--exit-code 1 \
supabase/gotrue:v2.185.0
# JSON 리포트 생성 (추후 분석·보관용)
trivy image \
--format json \
--output trivy-report.json \
supabase/studio:latestTrivy와 Grype를 병행하면 취약점 데이터베이스 차이로 생기는 누락을 보완할 수 있습니다. 두 스캐너가 서로 다른 CVE를 잡아내는 경우가 실제로 있거든요.
# Grype로 동일 이미지 교차 검증
grype supabase/gotrue:v2.185.0
# SBOM 기반 스캔: 이미지 레이어 분석 없이 패키지 매니페스트 전체를 열거하기 때문에
# 런타임에 설치된 패키지까지 탐지할 수 있어 일반 스캔보다 더 상세합니다
syft supabase/postgres:15.6.1.143 -o json | grype예시 4: CrowdSec으로 런타임 공격 탐지
패치만으로는 부족합니다. 알려지지 않은 취약점(Zero-day)이나 설정 실수를 노리는 공격에 대비하려면 런타임 보호가 필요합니다. CrowdSec의 supabase-compose 컬렉션은 Kong과 PostgreSQL 로그를 파싱해 SQL 인젝션, XSS, 브루트포스를 실시간으로 탐지합니다.
# supabase-compose 컬렉션 설치
# Kong 로그 파서 + SQL 인젝션/XSS/브루트포스 탐지 시나리오 포함
cscli collections install crowdsecurity/supabase-compose
# 설치된 컬렉션 확인
cscli collections list
# 탐지된 공격 현황 조회
cscli decisions listCrowdSec을 Supabase 스택에 사이드카로 붙이는 방식은 docker-compose.yml에 서비스를 추가하는 형태입니다.
services:
crowdsec:
image: crowdsecurity/crowdsec:latest
volumes:
- ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml
- /var/log/kong:/var/log/kong:ro # Kong 컨테이너 로그 볼륨 경로에 맞게 조정
- crowdsec-db:/var/lib/crowdsec/data
environment:
COLLECTIONS: "crowdsecurity/supabase-compose"
restart: unless-stopped
volumes:
crowdsec-db:Kong 로그 수집 경로는 실제 Kong 컨테이너의 볼륨 마운트 경로에 맞게 조정이 필요합니다. 적용 후 iptables/nftables 또는 Cloudflare Bouncer를 연결하면 탐지된 IP를 자동 차단할 수 있습니다.
장단점 분석
장점
| 항목 | 내용 |
|---|---|
| 데이터 주권 | 데이터가 외부로 나가지 않아 규제 대응에 유리합니다 |
| 인프라 제어 | 방화벽, SSL/TLS, RLS 등 보안 정책을 직접 설계할 수 있습니다 |
| 네트워크 격리 | 내부망 전용 구성으로 외부 노출 자체를 차단할 수 있습니다 |
| 커스터마이징 | 스택 구성 요소를 필요에 맞게 교체하거나 제거할 수 있습니다 |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| 수동 패치 | CVE 모니터링과 패치를 운영자가 직접 해야 합니다 | OpenCVE 알림 설정 + 자동 스캔 파이프라인 구성 |
| 다중 이미지 관리 | 6개 이상의 컨테이너 이미지를 개별 추적해야 합니다 | Trivy + Grype CI/CD 통합으로 자동화 |
| 시크릿 산재 | JWT 시크릿, DB 패스워드, API 키가 여러 컴포넌트에 분산됩니다 | Vault, AWS Secrets Manager 등 시크릿 매니저 도입 |
| 스캐너 공급망 리스크 | 스캔 도구 자체가 침해될 수 있습니다 (Trivy Docker Hub 사례) | 검증된 특정 버전 digest 핀닝 필수 |
| 자동화 부재 | Supabase Cloud 대비 보안 업데이트 자동 적용이 없습니다 | Renovate Bot 또는 Dependabot으로 이미지 업데이트 PR 자동화 |
실무에서 가장 흔한 실수
-
RLS를 테이블 생성 직후 설정하지 않는 경우 — Supabase는 기본적으로 RLS가 비활성화된 상태로 테이블을 만듭니다. 2025년 Security Retro에서 Event Trigger로 RLS 자동 강제를 추가했지만, 기존 테이블은 소급 적용되지 않습니다. Supabase 대시보드 > Security 탭의 Security Advisor에서 RLS 미설정 테이블을 한눈에 확인해볼 수 있습니다.
-
스캐너 이미지를 latest 태그로 고정해두는 경우 — Trivy Docker Hub 공급망 침해처럼, 스캐너 자체가 악성 코드를 실행하는 경로가 될 수 있습니다. CI/CD에서
trivy:latest대신trivy@sha256:<digest>형식으로 핀닝하는 것이 안전합니다. -
Docker Compose 버전을 오래 방치하는 경우 — 애플리케이션 이미지만 업데이트하고 Docker Compose 자체는 방치하는 경우가 많습니다. CVE-2025-62725처럼 Docker Compose 자체가 공격 벡터가 될 수 있으므로, v2.40.2 이상을 유지해두는 게 좋습니다.
마치며
셀프호스팅 Supabase의 보안은 '설치하면 끝'이 아니라, 스캔-평가-패치-검증의 사이클을 꾸준히 돌리는 운영의 문제입니다.
지금 바로 시작해볼 수 있는 3단계:
-
현재 이미지를 스캔해보는 것부터 시작해볼 수 있습니다. 실행 중인 postgres 이미지 태그를 먼저 확인하고(
docker inspect --format '{{index .RepoTags 0}}' $(docker ps -q -f name=supabase_db)),trivy image --severity CRITICAL,HIGH supabase/postgres:<태그>로 CRITICAL/HIGH만 좁혀서 보시면 결과가 많아도 수월하게 볼 수 있습니다. -
OpenCVE에서 Supabase 벤더 알림을 구독해두면 좋습니다.
https://app.opencve.io/cve/?vendor=supabase에서 Vendors 탭에 supabase를 추가하면 새 CVE 발생 시 이메일 알림을 받을 수 있어, 수동으로 NVD를 확인하는 수고를 크게 줄일 수 있습니다. -
docker compose version으로 Compose 버전을 확인하고, v2.40.2 미만이라면 업데이트해두는 게 빠릅니다. 서비스 중단 없이 가능하고, 읽기 전용 명령에서도 트리거되는 CVE-2025-62725를 막는 가장 확실한 방법입니다.
참고 자료
- Supabase Security Retro: 2025 | Supabase 공식 블로그
- Self-Hosting with Docker | Supabase Docs
- Security at Supabase
- CVE-2026-31813: Supabase Auth Bypass Vulnerability | SentinelOne
- CVE-2025-62725 Detail | NVD
- CVE-2025-62725: From "docker compose ps" to System Compromise | Imperva
- Docker fixes serious vulnerabilities in Compose and Desktop Installer | Techzine
- Hardening self-hosted Supabase with CrowdSec | CrowdSec 공식 블로그
- Trivy supply chain compromise: What Docker Hub users should know | Docker 공식 블로그
- Supabase CVEs and Security Vulnerabilities | OpenCVE
- Supabase: Products and vulnerabilities | CVE Details
- Security testing of your Supabase projects | Supabase Docs