Tech_News

github.dev에서 한 번 클릭으로 GitHub 토큰이 털린다 - VSCode 웹뷰 버그 뜯어보기

TeEm0 2026. 6. 4. 09:06

github.dev에서 한 번 클릭으로 GitHub 토큰이 털린다 - VSCode 웹뷰 버그 뜯어보기

왜 지금 이게 화제인가

오늘 HN 상위에 "1-Click GitHub Token Stealing via a VSCode Bug"가 올라왔고, 한국 쪽 GeekNews(hada.io)에도 번역 요약이 같이 떴다. 점수도 479점으로 꽤 높다. 보안 버그 글이 이렇게 빠르게 화제가 되는 건 보통 두 가지 이유다. (1) 공격 조건이 비현실적이지 않고, (2) 영향받는 대상이 우리 다수라는 것. 이번 건은 둘 다 해당된다.

핵심은 이거다. github.dev(저장소 보면서 . 키 누르면 뜨는 브라우저 VSCode)는 사용자의 GitHub OAuth 토큰을 들고 동작한다. 그런데 이 토큰이 특정 저장소로 스코프가 제한돼 있지 않아서, 사용자가 접근 가능한 모든 저장소(프라이빗 포함)를 읽고 쓸 수 있다. 여기에 VSCode 웹뷰(webview)의 격리가 깨지는 버그가 결합되면, 악성 저장소를 github.dev로 한 번 열어보는 것만으로 토큰이 새어나갈 수 있다는 게 요지다.

우리 입장에서 왜 무서우냐면, github.dev는 "그냥 코드 잠깐 볼 때" 무심코 쓰는 도구라서다. PR 리뷰하다가, 남이 보낸 링크 따라가다가, 점 키 한 번 누르는 행동에 보안 의식이 거의 안 들어간다.

동작 원리 - 어디서 격리가 깨지나

먼저 정상 구조를 보자. github.dev의 VSCode는 확장(extension)이나 렌더러가 만든 HTML을 그냥 메인 페이지에 박지 않는다. vscode-webview:// 스킴을 쓰는 샌드박스 iframe 안에 격리해서 띄운다. 이 iframe은 출처(origin)가 달라서, 정상적이라면 부모 페이지(github.dev)의 토큰이나 쿠키, 메시지에 마음대로 접근하지 못한다.

[github.dev 메인 origin]  ← 여기 OAuth 토큰이 산다
        │
        │ postMessage 등 제한된 통로
        ▼
[vscode-webview:// iframe]  ← 확장/프리뷰 렌더링용 (격리되어야 정상)

문제는 이 격리가 완벽하게 강제되지 않는 경로가 있었다는 것이다. 마크다운 프리뷰나 특정 렌더링 기능을 통해 공격자가 제어하는 콘텐츠가 웹뷰 안에서 실행되고, 거기서 부모 컨텍스트로 메시지를 보내거나 권한 경계를 우회하는 식으로 토큰에 도달하는 흐름으로 보인다. (정확한 익스플로잇 체인은 원문 PoC 확인 필요)

비유하자면 이렇다. 회사 건물에 외부인 면회실(웹뷰 iframe)을 따로 뒀다. 면회실에서는 사무실(메인 origin)로 못 들어가게 돼 있어야 하는데, 면회실 벽에 점검용 쪽문이 하나 열려 있던 거다. 면회 온 척하면서 그 문으로 들어가 책상 위 출입카드(토큰)를 집어 나오는 그림.

그리고 결정타가 토큰 스코프다. 이 출입카드가 "회의실 한 곳"만 여는 카드였으면 피해가 제한적인데, 건물 전체 마스터키였던 게 문제다. github.dev 토큰이 단일 저장소로 제한되지 않으니, 한 번 새면 그 사람이 접근 가능한 사내 프라이빗 저장소 전부가 위험해진다.

# 토큰 스코프를 확인하는 가장 단순한 방법 (PAT 기준)
curl -sI -H "Authorization: Bearer $TOKEN" https://api.github.com/user \
  | grep -i x-oauth-scopes
# x-oauth-scopes: repo, read:org ...
# repo 가 통째로 들어가 있으면 그 계정의 모든 repo에 read/write 권한

실무 관점 - 우리가 뭘 해야 하나

이 버그 자체는 GitHub/MS가 패치하는 영역이라 우리가 코드로 막을 건 아니다. 다만 이걸 계기로 점검할 게 명확하다.

1. "토큰 스코프 최소화"가 왜 진짜 중요한지 보여주는 사례

이번 사건의 피해 규모는 결국 토큰이 너무 넓었기 때문에 커졌다. 실무에 그대로 적용된다. 자동화나 CI에서 토큰 쓸 때 습관처럼 repo 풀 스코프 PAT를 박아두는 경우가 많은데, 이게 정확히 같은 종류의 위험이다. 하나 새면 전부 털린다.

  • 가능하면 Fine-grained PAT를 써서 저장소별로 권한을 쪼개라. classic PAT의 repo는 사실상 전 저장소 read/write다.
  • CI에서는 PAT 대신 GitHub App / OIDC 기반 단기 토큰을 우선 검토. 만료가 짧으면 유출돼도 창이 짧다.
  • 조직 차원에서 SSO 강제 + PAT 만료 정책을 걸어둬라.

2. github.dev / 브라우저 IDE를 신뢰 경계 안에서 다뤄라

"그냥 코드 보는 뷰어"라고 생각하지만, 실제로는 내 계정 권한을 들고 임의 저장소 콘텐츠를 렌더링하는 환경이다. 즉 신뢰하지 않는 저장소를 github.dev로 여는 행위 = 신뢰하지 않는 코드를 내 권한 컨텍스트에서 처리하는 것에 가깝다. 모르는 사람이 보낸 repo 링크에 점 키 누르는 건, 모르는 첨부파일 여는 거랑 보안 등급이 비슷하다고 생각하는 게 안전하다.

3. 흔한 함정

  • "프라이빗이라 괜찮겠지"는 함정이다. 이번 케이스는 내 토큰으로 내 프라이빗 저장소까지 읽히는 구조라 프라이빗 여부가 방어가 안 된다.
  • 로컬 VSCode도 안심 금지. 데스크톱 VSCode도 웹뷰를 쓰고, 마크다운 프리뷰·확장 프로그램이 신뢰 안 되는 콘텐츠를 렌더링하는 구조는 같다. 출처 불명 repo를 클론해서 프리뷰 여는 패턴 자체를 경계할 것.
  • 패치만 믿고 끝내지 말 것. 토큰이 이미 유출됐다고 가정하고 사후 점검(이상 로그인, 신규 PAT 발급 이력)을 하는 게 인시던트 대응의 기본이다.

4. 지금 당장 할 점검 리스트

# 내 계정에 발급된 OAuth 앱/토큰 권한 확인
GitHub → Settings → Applications → Authorized OAuth Apps

# 발급해둔 PAT 점검 (오래되고 넓은 스코프부터 폐기)
GitHub → Settings → Developer settings → Personal access tokens

# 조직 관리자라면
Org Settings → Third-party access / PAT policies 검토
감사 로그(Audit log)에서 비정상 repo 접근 패턴 확인

정리

한 줄 요약: github.dev가 들고 있는 GitHub 토큰이 전 저장소 권한이라, 웹뷰 격리 버그 한 방에 계정 전체가 노출될 수 있었다. 버그 자체는 패치 대상이지만, 교훈은 "토큰 스코프 최소화"와 "브라우저 IDE도 신뢰 경계로 취급하라"로 명확하다.

특히 신경 써야 할 사람: 조직 GitHub를 관리하는 인프라/플랫폼 팀, CI에 PAT를 박아 운영 중인 팀, 외부 오픈소스 저장소를 github.dev로 자주 들여다보는 사람. 지금 PAT 목록 한 번 열어서 풀 스코프짜리 오래된 토큰부터 정리하는 게 이 글을 읽고 할 수 있는 가장 효율 좋은 액션이다.

(상세 익스플로잇 체인과 패치 상태는 빠르게 바뀔 수 있으니 원문과 GitHub 보안 공지 확인을 권한다.)

참고 자료

사진: Microsoft Copilot / Unsplash

728x90