🔥 Vercel 2026년 4월 보안 사고: OAuth 공급망과 내가 확인한 6가지

#security#vercel#oauth#devops#incident
1129자
14분

OAuth 공급망 침해 일러스트

공지를 봤을 때 제일 먼저 연 건 코드가 아니라 Vercel 대시보드였다. 사이드 프로젝트 몇 개가 거기서 돌고 있다. 운영 로그 탭, environment variables 탭, 그다음엔 Google Workspace 보안 센터. 커피는 식었다.

무슨 일이 터졌나

Vercel 공식 공지에 따르면 2026년 4월 19일, 특정 내부 시스템에 대한 무단 접근이 확인됐다. 사고 대응 전문가를 투입했고, 법집행 기관에도 신고했다. 영향 받은 고객은 "제한된 일부"로, 해당 고객에게는 직접 연락하고 있다고 한다. 서비스 자체는 정상 운영 중이라는 말도 덧붙였다.

공지에는 세 가지 권고가 붙어 있다. 계정 activity log 검토, environment variable 로테이션, 그리고 앞으로는 "sensitive" 플래그를 적극적으로 쓰라는 것. 공지 맨 아래에 Indicator of Compromise로 OAuth 앱 client ID 하나가 공개됐다.

OAuth App:
110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com
OAuth App:
110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com

Google Workspace 관리자라면 이 앱을 내 도메인에서 누가 승인했는지 지금 당장 확인해 볼 값어치가 있다. 나는 먼저 이것부터 했다.

시작점은 제3자 OAuth 앱이었다

공지가 흥미로운 건, Vercel 스스로가 사고의 시작점을 "작은 제3자 AI 도구"라고 적었다는 점이다. Vercel 시스템 자체의 취약점이 아니라, 그 AI 도구의 Google Workspace OAuth 앱이 더 넓은 범위의 침해 대상이 됐다는 것. 해당 앱을 설치한 수백 개의 조직이 잠재적 영향권이라고 한다.

Vercel은 그 AI 도구의 이름을 공지에 쓰지 않았다. 하지만 BleepingComputer 보도는 Vercel CEO Guillermo Rauch의 X 설명을 근거로 그 도구를 Context.ai로 지목했다. Rauch의 설명대로라면 Vercel 직원의 Google Workspace 계정이 이 AI 도구에서 일어난 침해를 통해 탈취됐고, 공격자는 그 계정을 발판 삼아 내부 환경으로 권한을 올려갔다. 이 귀속 자체는 Vercel KB 공지 본문이 확인해 준 내용은 아니라는 점은 명심할 필요가 있다. 다만 공지의 "작은 제3자 AI 도구"라는 표현은 외신 보도와 맞물린다.

누가 훔쳐 갔다고 주장하는가

공지가 나온 직후 BreachForums에서 "ShinyHunters"를 자칭하는 사용자가 Vercel 내부 데이터를 판매한다는 글을 올렸다. BleepingComputer 보도에 따르면 이 사용자는 Telegram을 통해 Vercel 측과 접촉했고 약 200만 달러 규모의 거래를 주장했다고 한다. 주장 품목은 화려하다. 내부 데이터베이스, 액세스 키, 소스 코드, 직원 계정, API key, NPM token, GitHub token, 그리고 내부 Linear 자료까지. Next.js의 주간 npm 다운로드가 수천만 건에 달한다는 걸 감안하면, NPM token 한 장의 파급 효과는 Vercel 한 회사 문제로 그치지 않는다.

그런데 같은 BleepingComputer 보도에 중요한 토막이 있다. 최근 ShinyHunters 명의의 공격에 연루된 행위자들이 "우리는 이번 건과 무관하다"고 부인했다는 것. 이름값을 도용한 사칭일 가능성을 열어 두는 대목이다. Vercel 자체도 어떤 데이터가 실제로 유출됐는지는 아직 공개하지 않았다. 판매 글의 진위도 독립 검증되지 않았다고 BleepingComputer는 명시한다. 나는 이 대목에서 한 템포 쉬었다. 과장된 주장은 싸고, 검증된 침해는 비싸다. 판단을 멈추고 할 일부터 하는 게 맞다.

sensitive env var이 사실상 방파제였다

Vercel의 sensitive environment variables 기능은 2024년 2월에 공식 기능으로 자리잡았다. 평범한 env var과의 차이는 공식 문서 표현을 그대로 빌리면 "생성 후에는 읽을 수 없는 형태로 저장된다"는 것이다. 프로젝트 권한이 있는 사용자라도 UI에서 값을 다시 꺼내 볼 수 없고, 대시보드에 표시되지 않는다. 해독 타이밍이 정확히 어디까지 제한되는지는 공식 문서들 사이에서도 표현이 조금씩 엇갈린다. 다만 "저장 이후 사람이 다시 읽을 수 없다"는 보증은 일관된다.

이번 공지에서 Vercel은 이렇게 적었다. "sensitive로 표시된 값이 접근됐다는 증거는 현재 없다." 반대로 말하면, sensitive로 표시하지 않은 env var은 침해 범위 안에 있었을 가능성이 있다는 뜻이다. 그래서 권고의 우선순위가 명확해진다. sensitive 플래그 없이 넣어 둔 API key, database 자격증명, signing key는 일단 유출된 것처럼 대하고 지금 로테이션하라는 것.

이 대목을 읽으면서 내가 부끄러웠던 건, 내 프로젝트 몇 개에 여전히 평범한 env var로 박혀 있는 OpenAI key와 Supabase service role key였다. 개발 초기에 빠르게 넣어 놓고, 나중에 옮기자고 미뤄 놨던 것. "나중"이 오늘이었다.

2025년 Salesloft Drift를 떠올렸다

OAuth 기반 공급망 공격이 새로 생긴 패턴은 아니다. 2025년 8월, Salesloft Drift 사건에서 이미 똑같은 구조가 드러났다. Drift라는 영업 채팅 도구의 OAuth token이 탈취되면서, 그 도구를 설치한 700개 이상의 조직이 영향권에 들어갔다. Google Threat Intelligence는 이 공격자를 UNC6395로 추적한다. 당시에도 Salesforce 객체를 타고 들어가 AWS key, Snowflake token, 자격증명 같은 "비밀 안의 비밀"이 새 나갔다.

이번 Vercel 건이 2025년의 Drift와 얼마나 닮아 있는지 보면 좀 불편해진다. 탈취 경로는 직접 공격이 아니라 내가 승인한 OAuth 앱이다. 피해 표면은 그 앱을 설치한 모든 고객사로 번진다. SaaS 하나하나는 안전해도, 내가 여기저기 꽂아 둔 연결의 총합이 실제 공격면이 된다.

이 점이 진짜 교훈이라고 생각한다. "제가 만든 백엔드는 안전합니다"라는 말은 한참 전에 충분조건이기를 멈췄다.

나는 그래서 뭘 했나

공지를 본 저녁, 내가 실제로 한 일은 이런 순서였다.

  1. Google Workspace 보안 센터 → OAuth 앱 목록 → IOC에 공개된 client ID를 검색. 다행히 내 도메인엔 없었다. 없어도 한 번쯤은 돌려야 한다.
  2. Vercel 대시보드 → Activity log에서 최근 2주간 낯선 IP나 지역, env var 조회 이벤트 훑기. CLI로도 조회할 수 있다.
  3. Environment variables 페이지에서 sensitive 플래그가 꺼져 있는 값을 전부 찾아 목록화. 개인 프로젝트 기준으로 17개였다.
  4. 그중 시크릿 성격인 것(OpenAI, Supabase, Stripe, R2)은 각 벤더에서 신규 발급 → Vercel에 새 값 주입 → sensitive 플래그로 재등록 → 기존 key revoke.
  5. 팀 프로젝트는 아직이다. 공유 저장소이기도 하고, 빌드 파이프라인에 맞물린 값이 많아 PR로 정리하기로 했다.
  6. GitHub Personal Access Token도 한 번 갈아 끼웠다. 직접적 관련은 없지만, 이런 날엔 같이 정리하는 쪽이 마음이 편하다.

여기까지 대략 90분 걸렸다. 주말을 통째로 쓸 각오였는데, sensitive 플래그 쓰는 환경이라면 90분이면 된다는 게 작은 위안이었다.

드는 생각

솔직히 Vercel을 비난하는 글을 쓰고 싶지는 않다. 공지 타임라인과 내용은 이례적으로 빨랐고, 구체적인 IOC까지 공개한 점은 드물다. 나라면 더 오래 걸렸을 거다. 다만 한 가지는 분명해진다. 내가 쓰는 SaaS의 OAuth 앱 목록을 주기적으로 감사하지 않았던 건 내 게으름이 맞다.

AI 도구 회원가입 화면을 떠올려 보면, "Google로 계속하기" 버튼이 10초 만에 눈앞에 와 있다. 그중 상당수가 그 자리에서 내 Gmail, Drive, Calendar, Admin 엔드포인트까지 오갈 수 있는 scope을 달라고 한다. 나는 그걸 읽지 않고 승인한 적이 셀 수 없이 많다. 이번 공지가 진짜 불편한 지점이 거기다. 공격자는 Vercel을 뚫은 게 아니라 내가 아무렇게나 승인한 연결의 사슬을 뚫었다.

이번 주말 할 일 목록에 한 줄을 더 적어 뒀다. Google Workspace의 Third-party app access 페이지에서 최근 2년간 승인한 앱을 전부 꺼내 보기. 기억나지 않는 이름은 지우기. 이게 블로그 글 한 편보다 내 장기 보안에 훨씬 더 도움이 될 것 같다.

아직 Vercel의 후속 공지를 지켜보고 있다. 실제로 어떤 데이터가 새어 나갔는지, sensitive 플래그의 방어 가정이 실전에서 어디까지 유효했는지, 공식 사후 분석(post-mortem)이 나오면 다시 읽을 생각이다. 그때는 오늘 내가 한 90분의 작업이 헛수고였는지 아닌지도 더 명확해질 것 같다.

참고 자료

YouTube 영상

채널 보기
투영과 예측, 그리고 선형 결합 | 선형대수학
벡터의 정의와 덧셈 연산 | 선형대수학
직교성과 벡터 투영 | 선형대수학
트라이(Trie) 자료구조: 파이썬으로 삽입(Insert) 연산 구현하기 | Trie 자료구조 이야기
마지막편, 트라이 노드를 50% 이상 줄이는 방법? 압축 트라이 성능 분석 | Trie 자료구조 이야기
Trie 자료구조 파이썬 구현: Search와 Starts With 연산 | Trie 자료구조 이야기
행렬의 가장 중요한 연산 - 행렬 곱셈 | 선형대수학
AI 추천 시스템의 원리, 벡터 사이의 각도와 코사인 유사도 | 선형대수학