Docker Sandboxes sbx cp 취약점(CVE-2026-103916) 해부: AI 에이전트의 심볼릭 링크 탈출과 v0.51.0 점검하기
AI 코딩 에이전트 격리 도구인 Docker Sandboxes의 sbx cp 심볼릭 링크 탈출 취약점(CVE-2026-103916) 원리와 v0.51.0 패치 내역을 정리한다. virtio-fs 허용 목록과 호스트 복사 채널의 경계, 부모 경로 심볼릭 링크 검증 방법을 살펴본다.
microVM의 virtio-fs 공유 폴더 허용 목록(녹색 경로)과 별개로 동작하던 sbx cp 복사 채널(상단 경로)에서 부모 심볼릭 링크 탈출을 경로 가두기 방패(v0.51.0)로 차단하는 개념 일러스트다. 실제 도구 화면이 아니다.
Claude Code, OpenAI Codex, Gemini CLI 같은 코딩 에이전트를 로컬 PC에서 격리 실행하기 위해 사용하는 Docker Sandboxes(sbx CLI)에서, 샌드박스 내부 에이전트가 심볼릭 링크(Symlink)를 심어 호스트의 민감 파일을 읽거나 덮어쓸 수 있는 고위험 취약점(CVE-2026-103916, CVSS 3.1 8.2 High, CWE-59)이 공개되었다. 함께 공개된 호스트 Git 설정 기반 임의 코드 실행 취약점(CVE-2026-121614)은 v0.50.0에서, sbx cp 심볼릭 링크 우회 취약점인 CVE-2026-103916은 2026년 11월 3일 배포된 v0.51.0에서 최종 수정되었다.
결론부터 말하면 microVM의 virtio-fs 공유 폴더 허용 목록(Allowlist)이 안전하더라도, 호스트 권한으로 동작하는 sbx cp 복사 채널은 별도의 보안 경계로 취급해야 한다. 특히 당초 패치 예정이었던 v0.48.0(10월 13일)에서는 수정이 불완전했으므로 반드시 v0.51.0 이상으로 업그레이드해야 하며, 패치 전이거나 에이전트가 복사 명령을 제안할 때는 마지막 파일명(Leaf)만 검사하는 -L 플래그에 의존하지 말고 경로의 모든 부모 디렉터리 구성요소까지 realpath로 검증해야 한다.
이 글은 취약점 발견자인 Endor Labs의 CVE-2026-103916 기술 분석 보고서와 공식 CVE-2026-103916 레코드, ACN 보안 권고를 교차 검증해 정리한 대응 가이드다. 실제 취약 버전의 sbx 바이너리로 공격을 재현하지는 않았으며, 로컬 Python 검증 코드는 임시 디렉터리에서 부모·말단 심볼릭 링크 탐지 및 경로 가두기(Confinement) 방어 로직만 검증한다.
1. 왜 microVM 허용 목록(Allowlist)이 있어도 호스트 파일이 뚫렸는가
Docker Sandboxes는 일반 컨테이너와 달리 별도의 Linux 커널과 Docker 데몬을 가진 경량 가상머신(microVM) 안에서 에이전트를 실행한다. 사용자가 승인한 작업 폴더(Workspace)만 virtio-fs로 마운트되므로, 게스트 VM 내부에서 루트 권한으로 마운트를 시도해도 승인되지 않은 호스트 경로에는 접근할 수 없다.
문제는 호스트와 샌드박스 사이에 두 번째 파일 이동 경로인 sbx cp가 존재한다는 점이다.
| 구분 항목 | 채널 1: virtio-fs 공유 파일시스템 | 채널 2: sbx cp 호스트-샌드박스 복사 명령 (v0.28.0 ~ v0.50.x) |
| 실행 주체 및 권한 | microVM 하이퍼바이저가 노출 범위를 강제하며 게스트 커널 내부에 격리됨 | 호스트 OS의 sbx CLI 프로세스가 개발자(Operator) 본인의 전체 권한으로 일반 파일 I/O 수행 |
| 허용 목록(Allowlist) 참조 여부 | 승인된 작업 디렉터리만 마운트 가능 (Allowlist 강제 적용) | Allowlist를 참조하지 않음. CLI에 전달된 호스트 경로의 심볼릭 링크를 호스트 파일시스템에서 그대로 해석해 접근 |
| 게스트 내부에서 본 심볼릭 링크 | 에이전트가 작업 폴더 안에 /Users/me/.ssh 같은 호스트 경로로 심볼릭 링크를 만들면 게스트 내부에서는 대상이 없는 끊어진 링크(Dangling symlink)로 보임 | 사용자가 호스트에서 sbx cp를 실행하는 순간, 호스트 CLI가 해당 심볼릭 링크를 실제 호스트 경로로 해석해 읽기·쓰기를 수행함 |
| 출력 가시성 | sbx mount 실행 시 Mounted NOTION_MARKDOWN_ESCAPED_LT_SENTINELresolved> at NOTION_MARKDOWN_ESCAPED_LT_SENTINELtarget> 형태로 실제 경로 출력 | sbx cp 복사 성공 시 종료 코드 0만 반환하고 실제 해석된 호스트 경로를 출력하지 않아 사용자가 우회 여부를 눈치채기 어려움 |
즉, 에이전트가 프롬프트 인젝션 등에 오염되어 읽기·쓰기 권한이 있는 작업 폴더 안에 호스트의 ~/.ssh나 ~/.aws를 가리키는 심볼릭 링크를 심어두고 사용자에게 “빌드 결과물을 복사하라”거나 “로그 파일을 샌드박스로 넣어달라”고 일상적인 sbx cp 명령을 제안하면, 사용자가 명령을 실행하는 순간 격리 경계가 무너진다.
2. -L 플래그가 막아주지 못하는 4가지 심볼릭 링크 위치
과거 v0.38.0에서 수정된 CVE-2026-17106은 압축 아카이브 내부의 상대 경로가 추출 루트(Extraction root) 밖으로 탈출하는 것을 막았다. 그러나 추출 루트 자체나 복사 원본의 부모 디렉터리(Parent component)가 심볼릭 링크인 경우는 검사하지 않았다.
공식 분석 보고서가 확인한 sbx cp의 네 가지 심볼릭 링크 위치별 동작은 다음과 같다.
| 심볼릭 링크 위치 (Symlink Position) | 공격 방향 및 예시 | 기본 추종 여부 (Followed by default?) | -L 플래그 통제 여부 (Gated by -L?) | 실제 보안 영향 (CVE-2026-103916) |
| 1. 복사 출력 목적지 — 마지막 구성요소 (Copy-out destination, leaf) | 샌드박스 → 호스트 복사 시 목적지 폴더나 파일 자체가 심볼릭 링크 (예: work/results → ~/.ssh) | 예 (Yes) | 아니오 (No) — 목적지에는 -L이 무관함 | 임의 호스트 파일 덮어쓰기/생성 가능. ~/.zshrc, ~/.gitconfig, ~/.ssh/authorized_keys, .git/hooks 등을 덮어써 호스트 코드 실행으로 이어질 수 있음 |
| 2. 복사 출력 목적지 — 부모 구성요소 (Copy-out destination, parent) | 샌드박스 → 호스트 복사 시 목적지 상위 경로가 심볼릭 링크 (예: work/out/sub/file에서 work/out이 링크) | 예 (Yes) | 아니오 (No) | 임의 호스트 하위 경로 덮어쓰기 가능. 대상의 부모 디렉터리가 호스트에 이미 존재하기만 하면 어디든 쓰기 가능 |
| 3. 복사 입력 원본 — 마지막 구성요소 (Copy-in source, leaf) | 호스트 → 샌드박스 복사 시 파일 자체가 심볼릭 링크 (예: work/leaf.txt → ~/secret/notes.txt) | 아니오 (No) | 예 (Yes) — -L을 줄 때만 따라감 | 유일하게 정상 방어되는 위치. 기본 실행 시 링크 자체만 복사되어 게스트 안에서 끊어진 링크로 남음 |
| 4. 복사 입력 원본 — 부모 구성요소 (Copy-in source, parent) | 호스트 → 샌드박스 복사 시 파일의 부모 폴더가 심볼릭 링크 (예: work/vendor → ~/.aws, 복사 대상은 work/vendor/credentials) | 예 (Yes) | 아니오 (No) — -L 없이도 무조건 따라감 | 호스트 민감 파일 탈취(Read) 가능. 마지막 구성요소( credentials)는 일반 파일이므로 -L 검사를 우회해 호스트 파일을 샌드박스 안으로 반입함 |
결국 4개 위치 중 3개 위치가 -L 플래그와 무관하게 기본 열려 있었다. 특히 4번(Copy-in 부모 심볼릭 링크)의 경우, 샌드박스 안의 대상 경로가 존재하지 않아 복사가 실패하더라도 Can't add file /Users/me/... to tar 형태의 오류 메시지에 호스트의 실제 해석 경로가 노출되는 부작용까지 확인되었다.
3. 버전별 패치 내역과 함께 확인할 Docker 보안 업데이트
이번 권고에서는 CVE-2026-103916 외에도 Docker Sandboxes 및 관련 도구의 취약점이 함께 다뤄졌으므로 버전 숫자를 정확히 구분해야 한다.
| 식별자 및 대상 제품 | 영향 받는 버전 범위 | 수정 완료 버전 | 핵심 내용 및 주의사항 |
| CVE-2026-103916 (Docker Sandboxes sbx cp) | 0.28.0 이상 ~ 0.51.0 미만 | 0.51.0 (2026-11-03 배포) | sbx cp 시 호스트 경로를 공유 작업 공간 내부로 안전하게 가두지 못하는 문제(CWE-59). 당초 예정된 0.48.0(10월 13일) 패치는 불완전했으므로 반드시 0.51.0 이상인지 확인해야 함 |
| CVE-2026-121614 (Docker Sandboxes Git 설정) | 0.31.0 이상 ~ 0.50.0 미만 | 0.50.0 | 읽기·쓰기 마운트된 직접 모드(Direct-mode) 샌드박스에서 저장소의 Git 설정을 변조해 호스트 측 Git 명령 실행 시 사용자 권한으로 임의 프로그램을 실행할 수 있는 문제(CWE-15) |
| Docker Buildx 및 Docker Desktop (연관 보안 업데이트) | Buildx 0.21.0 ~ 0.37.2 미만,Desktop 4.98.0 미만 | Buildx 0.37.2Desktop 4.98.0 | 2026년 11월 초 보안 권고에 포함된 연관 컴포넌트 업데이트로, sbx CLI와 함께 최신 패치 상태를 유지하는 편이 안전함 |
4. 로컬 Python으로 검증하는 경로 구성요소별 심볼릭 링크 차단 로직
왜 마지막 구성요소만 확인하는 os.path.islink(path) 방식이 실패하는지, 그리고 호스트 측 파일 복사 도구가 어떻게 경로를 검증해야 하는지 표준 라이브러리만으로 재현·검증할 수 있다.
다음 Python 스크립트는 작업 공간 루트(workspace_root)부터 대상 경로까지의 모든 중간 부모 구성요소를 순회하며 심볼릭 링크 여부를 검사하고, 최종 realpath가 작업 공간 내부에 머무는지 확인한다.
직접 실행해 확인한 범위
위 스크립트를 로컬 Linux Python 환경에서 실행해 세 가지 경계를 확인했다.
- 말단 심볼릭 링크(
work/leaf.txt): 단순 Leaf 검사와 전체 경로 순회 검사 모두 정상적으로 차단(leaf_symlink_blocked:leaf.txt)했다.
- 부모 디렉터리 심볼릭 링크(
work/vendor/notes.txt):notes.txt자체는 일반 파일이기 때문에naive_leaf_only_check()는True를 반환하며 뚫렸지만,verify_workspace_confinement()는 상위 구성요소인vendor에서 심볼릭 링크를 감지해parent_symlink_detected:vendor로 정확히 차단했다.
- 정상 하위 디렉터리(
work/artifacts/build.log): 심볼릭 링크가 없는 일반 하위 폴더 경로는confined:...로 통과했다.
단, 실제 파일 복사 도구를 구현할 때는 확인 시점과 실제 파일 열기 시점 사이의 경쟁 상태(TOCTOU)까지 막기 위해 Go의 cyphar/filepath-securejoin이나 Linux의 openat2(..., RESOLVE_NO_SYMLINKS | RESOLVE_BENEATH) 계열 호출을 결합해야 한다.
5. 실무 점검 및 안전한 샌드박스 운영 체크리스트
- Docker Sandboxes
v0.51.0이상 즉시 업데이트: 터미널에서sbx version을 확인해0.51.0미만(특히 불완전 패치였던0.48.0~0.50.x)이라면 즉시 최신 버전으로 업그레이드한다.
- 복사 전 호스트 측
realpath및 심볼릭 링크 점검: 업그레이드 전이거나 에이전트가 작업 폴더 내부 경로로sbx cp명령을 제안할 때는 실행 전에 아래 명령으로 실제 해석 경로와 작업 공간 내부 심볼릭 링크 유무를 먼저 확인한다.
- 공유 작업 폴더 밖의 전용 스테이징 폴더 사용: 호스트와 샌드박스 사이에 파일을 주고받을 때는 에이전트가 쓰기 권한을 가진 공유 작업 폴더(Workspace) 내부 경로 대신, 샌드박스에 마운트된 적이 없는 호스트의 별도 빈 디렉터리를
sbx cp의 호스트 측 경로로 사용하는 편이 안전하다.
- 저장소
.git/config및 훅 변조 여부 확인:CVE-2026-121614와 유사하게 에이전트가 마운트된 저장소의.git/config(예:core.pager,core.fsmonitor,core.sshCommand)나.git/hooks/를 수정했는지 호스트에서git status나git diff를 실행하기 전에 점검한다.
참고 자료
확인 기준일: November 5, 2026
English version:
Docker Sandboxes sbx cp Vulnerability (CVE-2026-103916): How Parent Symlinks Bypass Agent Isolation and What v0.51.0 Fixes