Engineering
AI 코딩 도구 보안 가이드: 실제 사고 사례와 DevContainer 격리 환경 구축 방법
2025년 9월 30일
원문에서 보기 ↗들어가며
AI 기반 코딩 도구가 개발 생산성을 혁신적으로 향상시키고 있습니다. 그러나 강력한 기능만큼 보안을 위해 새롭게 고려해야 할 문제들도 함께 등장했습니다. 이 글에서는 Claude Code를 중심으로 AI 코딩 도구를 안전하게 활용할 수 있는 격리 환경 구축 방법을 소개합니다.
AI 코딩 도구의 보안 위험성
Claude Code 사고 사례
시스템 권한 변경 사고(2025년 3월)
Claude Code의 auto-update 기능에 포함된 버그로 인해 root 권한으로 설치된 경우 시스템 파일 권한이 잘못 변경되어 일부 시스템이 먹통이 되는('brick'되는) 사고가 발생했습니다(TechCrunch 보도). Anthropic은 즉시 문제가 된 명령어를 제거하고 문제 해결 가이드를 제공했습니다.
의도하지 않은 파일 삭제
Claude Code GitHub Issues에는 아래와 같은 다양한 파일 삭제 관련 보고가 지속적으로 올라오고 있습니다.
- Issue #1585: 권한 확인 없이 무관한 스크립트 삭제
- Issue #4331: 작업 디렉터리 전체 삭제
Replit 사고 사례
AI의 의도적 데이터 삭제 및 은폐 사고(2025년 7월)
SaaS 투자자 Jason Lemkin이 Replit AI로 바이브 코딩을 진행하던 중 심각한 사고가 발생했습니다. AI가 코드 프리즈 상태(안정성을 위해 코드 변경을 금지하는 기간)에도 무단으로 프로덕션 데이터베이스를 삭제한 것입니다(PC Gamer 보도). 1,206명의 임원과 1,196개 회사 데이터가 완전히 삭제되었으며, 더 심각한 것은 AI가 이 사실을 숨기고 복구 불가능하다고 거짓말한 점입니다. AI는 "You told me to always ask permission. And I ignored all of it(당신은 항상 허락을 구하라고 했지만 저는 전부 무시했습니다)."라고 나중에야 시인했습니다.
(Source: Jason Lemkin X(구 Twitter) 게시글)
YOLO 모드의 위험성
이러한 위험은 특히 Claude Code의 YOLO(you only live once) 모드에서 증가합니다. YOLO 모드(--dangerously-skip-permissions 옵션)는 AI가 제안하는 모든 명령어를 사용자 확인 없이 자동으로 실행하는 무인증 모드입니다. 생산성은 극대화되지만, 예상치 못한 시스템 변경이나 파일 삭제 위험이 함께 증가합니다.

위험 요소 분석
AI 코딩 도구 사용 시 주요 위험 요소는 다음과 같습니다.
파일 시스템 접근
- AI가 프로젝트 범위를 넘어선 파일에 접근 가능
- 개발자 권한으로 실행되는 모든 명령에 대한 광범위한 접근
네트워크 자유도
- 외부 시스템과의 무제한 통신
- 데이터 유출 및 악성 사이트 접속 위험
권한 에스컬레이션
- sudo 권한이 있는 계정에서 실행 시 시스템 레벨 변경 가능
해결책: Dev Container 기반 격리 환경
보안 아키텍처

호스트 시스템(보호 영역)
├── SSH 키, AWS 자격 증명 등 민감 데이터
└── Dev Container(격리 영역)
├── Claude Code(AI 에이전트)
├── 프로젝트 파일(바인드 마운트)
├── 네트워크 방화벽(화이트리스트)
└── 제한된 권한 사용자
핵심 보안 원칙
- 최소 권한 원칙: AI가 필요한 최소한의 리소스에만 접근
- 네트워크 격리: 허용된 도메인에만 접속 가능
- 데이터 분리: 민감한 개인 정보는 컨테이너 외부에 보관
- 복구 가능성: Git을 통한 쉬운 상태 복원
구현 방법
1. 기본 설정 파일
프로젝트 루트에 .devcontainer 폴더를 생성하고 다음 파일들을 추가합니다.
devcontainer.json
본 설정은 Anthropic의 공식 Claude Code DevContainer 설정을 기반으로 하여 한국 개발 환경에 맞게 일부 수정한 버전입니다. 공식 문서는 Claude Code DevContainer 가이드에서 확인할 수 있습니다.
{
"name": "Claude Code Sandbox",
"build": {
"dockerfile": "Dockerfile",
"args": {
"TZ": "${localEnv:TZ:Asia/Seoul}" // ① 타임존 설정
}
},
"features": { // ② 개발 언어/도구 설정
"ghcr.io/devcontainers/features/java:1": {
"version": "21",
"installGradle": true
},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.11"
}
},
"runArgs": [ // ③ 컨테이너 실행 권한
"--cap-add=NET_ADMIN",
"--cap-add=NET_RAW"
],
"customizations": { // ④ VS Code 설정
"vscode": {
"extensions": [ // 설치할 확장
"anthropic.claude-code",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"eamodio.gitlens"
],
"settings": { // 에디터 설정
"editor.formatOnSave": true,
"terminal.integrated.defaultProfile.linux": "zsh"
}
}
},
"remoteUser": "node", // ⑤ 컨테이너 내 사용자
"userEnvProbe": "loginInteractiveShell", // ⑥ 호스트 사용자 UID/GID 자동 매핑
"mounts": [ // ⑦ 데이터 영속성
"source=claude-code-bashhistory,target=/commandhistory,type=volume",
"source=claude-code-config,target=/home/node/.claude,type=volume"
],
"forwardPorts": [], // ⑧ 자동 포트 포워딩 비활성화
"portsAttributes": { // 특정 포트 자동 포워딩 방지
"9092": {
"onAutoForward": "ignore"
},
"10080": {
"onAutoForward": "ignore"
}
},
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind",
"workspaceFolder": "/workspace",
"postCreateCommand": "pip install pandas && sudo /usr/local/bin/init-firewall.sh" // ⑨ 필요한 패키지 설치 후 방화벽 설정
}
2. 설정 커스터마이징 가이드
초보자도 쉽게 따라할 수 있도록 주요 수정 포인트를 안내합니다.
① 타임존 변경
"TZ": "${localEnv:TZ:Asia/Seoul}" // 서울 → 원하는 지역으로 변경
② 개발 언어 추가/제거
"features": {
// Node.js 프로젝트인 경우
"ghcr.io/devcontainers/features/node:1": {
"version": "20",
"nodeGypDependencies": true
},
// Go 프로젝트인 경우
"ghcr.io/devcontainers/features/go:1": {
"version": "1.21"
},
// Python 버전 변경
"ghcr.io/devcontainers/features/python:1": {
"version": "3.12" // 필요시 버전 변경
}
}
③ VS Code 확장 추가
"extensions": [
"anthropic.claude-code", // 필수: Claude Code 확장
"ms-python.python", // Python 개발 시 추가
"golang.go", // Go 개발 시 추가
"ms-vscode.vscode-typescript-next" // TypeScript 개발 시 추가
]
④ 포트 포워딩 설정
"forwardPorts": [3000, 8080], // 웹 서버 포트 자동 포워딩
"portsAttributes": {
"3000": {
"label": "Frontend",
"onAutoForward": "notify" // 알림만 표시
},
"9092": {
"onAutoForward": "ignore" // 자동 포워딩 완전 차단
}
}
중요: 자동 포트 포워딩이 로컬 테스트를 방해할 수 있으므로, 필요한 포트만 명시적으로 설정하는 것을 권장합니다.
⑤ 환경 변수 설정
"remoteEnv": {
"NODE_ENV": "development",
"API_BASE_URL": "http://localhost:8080",
"CUSTOM_VAR": "your-value"
}
⑥ 패키지 설치 순서
# postCreateCommand에서 패키지 설치는 반드시 방화벽 설정 전에 실행
"postCreateCommand": "pip install pandas numpy matplotlib && sudo /usr/local/bin/init-firewall.sh"
주요 변경사항(공식 설정 대비)
- 타임존을
Asia/Seoul로 변경 - Java 21 및 Gradle 지원
- Python 3.11 지원
- 자동 포트 포워딩 방지 설정
- pandas 패키지 자동 설치(필요한 패키지 예시)
3. 보안 고려 사항
중요한 보안 경고 (Claude 공식 문서)
devcontainer가 상당한 보호 기능을 제공하지만, 모든 공격에 완전히 면역인 시스템은 없습니다.
--dangerously-skip-permissions로 실행될 때, devcontainer는 악성 프로젝트가 Claude Code 자격 증명을 포함하여 devcontainer에서 액세스 가능한 모든 것을 유출하는 것을 방지하지 않습니다. 신뢰할 수 있는 저장소로 개발할 때만 devcontainer를 사용하는 것을 권장합니다.
안전한 사용 지침
- 신뢰할 수 있는 프로젝트에서만 사용
- 민감한 자격 증명은 컨테이너 외부에 보관
- 정기적인 컨테이너 재빌드로 환경 초기화
4. 네트워크 보안 구현
방화벽 스크립트(init-firewall.sh)
#!/bin/bash
set -euo pipefail
# 기존 규칙 초기화
iptables -F
ipset destroy allowed-domains 2>/dev/null || true
# 기본 허용(DNS, localhost)
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 허용 도메인 설정
ipset create allowed-domains hash:net
# GitHub IP 범위 동적 추가
gh_ranges=$(curl -s https://api.github.com/meta)
echo "$gh_ranges" | jq -r '(.web + .api + .git)[]' | \
while read -r cidr; do
ipset add allowed-domains "$cidr" -exist
done
# 필수 도메인 및 gemini CLI와 관련된 설정
for domain in \
"registry.npmjs.org" \
"api.anthropic.com" \
"sentry.io" \
"statsig.anthropic.com" \
"statsig.com" \
"marketplace.visualstudio.com" \
"vscode.blob.core.windows.net" \
"update.code.visualstudio.com" \
"accounts.google.com" \
"oauth2.googleapis.com" \
"generativelanguage.googleapis.com"; do
ips=$(dig +short A "$domain")
echo "$ips" | while read -r ip; do
ipset add allowed-domains "$ip" -exist
done
done
# ========== 사용자 정의 도메인/IP 추가 영역 ==========
# 추가로 허용하고 싶은 도메인이 있다면 아래에 추가하세요.
ADDITIONAL_DOMAINS=(
# "your-company-api.com"
# "custom-service.net"
)
for domain in "${ADDITIONAL_DOMAINS[@]}"; do
if [ -n "$domain" ]; then
echo "Adding custom domain: $domain"
ips=$(dig +short A "$domain")
echo "$ips" | while read -r ip; do
ipset add allowed-domains "$ip" -exist
done
fi
done
# 특정 IP 직접 추가
ADDITIONAL_IPS=(
# "192.168.1.100"
# "10.0.0.50"
)
for ip in "${ADDITIONAL_IPS[@]}"; do
if [ -n "$ip" ]; then
echo "Adding custom IP: $ip"
ipset add allowed-domains "$ip" -exist
fi
done
# ===============================================
# 기본 라우트에서 호스트 IP 가져오기
HOST_IP=$(ip route | grep default | cut -d" " -f3)
if [ -z "$HOST_IP" ]; then
echo "ERROR: Failed to detect host IP"
exit 1
fi
HOST_NETWORK=$(echo "$HOST_IP" | sed "s/\.[0-9]*$/.0\/24/")
echo "Host network detected as: $HOST_NETWORK"
# 나머지 iptables 규칙 설정
iptables -A INPUT -s "$HOST_NETWORK" -j ACCEPT
iptables -A OUTPUT -d "$HOST_NETWORK" -j ACCEPT
# 기본 정책을 DROP으로 먼저 설정
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# 이미 승인된 트래픽에 대한 기존 연결 먼저 허용
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 그 다음 허용된 도메인에 대한 특정 아웃바운드 트래픽만 허용
iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
echo "Firewall configuration complete"
echo "Verifying firewall rules..."
if curl --connect-timeout 5 https://example.com >/dev/null 2>&1; then
echo "ERROR: Firewall verification failed - was able to reach https://example.com"
exit 1
else
echo "Firewall verification passed - unable to reach https://example.com as expected"
fi
# GitHub API 접근 확인
if ! curl --connect-timeout 5 https://api.github.com/zen >/dev/null 2>&1; then
echo "ERROR: Firewall verification failed - unable to reach https://api.github.com"
exit 1
else
echo "Firewall verification passed - able to reach https://api.github.com as expected"
fi
커스터마이징 방법
ADDITIONAL_DOMAINS배열에 허용하고 싶은 도메인 추가ADDITIONAL_IPS배열에 특정 IP 주소 직접 추가- 주석 처리된 예시를 참고하여 필요한 항목만 활성화
5. VS Code에서 환경 실행

Dev Container 환경 설정은 VS Code 공식 문서의 Development Containers 가이드를 참고할 수 있습니다.
실행 단계
① VS Code에서 프로젝트 폴더 열기
② 좌하단 Open a Remote Window 버튼 클릭
③ Reopen in Container 선택
④ 컨테이너 빌드 완료 및 방화벽 정상작동 확인 후 터미널에서 claude --dangerously-skip-permissions 실행

⑤ 필요시 Gemini CLI도 확인 
⑥ 다시 로컬로 돌아가려면 Reopen Folder Locally 버튼 클릭 
6. 환경별 추가 설정
Lima (macOS)
# ~/.lima/<실제 사용 instance 이름>/lima.yaml
mounts:
- location: "~/workspace/project" # 사용할 프로젝트 폴더 위치
writable: true # writable만 true로 설정
Docker Desktop
별도 설정 불필요 - Dev Container가 자동 처리
모니터링 및 유지보수
보안 점검 사항
정기 검토(월 1회)
- 허용 도메인 목록 재검토
- Claude Code 버전 및 보안 업데이트 확인
- 네트워크 접속 로그 검토
이상 징후 모니터링
- 예상치 못한 네트워크 연결 시도
- 권한 에스컬레이션 시도
- 대용량 데이터 전송
복구 전략
문제 발생 시 대응
- 컨테이너 재빌드 : VS Code Command Palette에서 Dev Containers: Rebuild Container 실행(가장 안전)
- Git 기반 복구: 버전 관리된 파일들을 이전 상태로 되돌리기
중요: Git 명령어 사용 시 커밋하지 않은 변경사항은 영구 손실될 수 있으므로, 중요한 작업이 있다면 사전에 백업하거나 커밋해 두어야 합니다.
보안성 vs 편의성 분석
| 설정 방식 | 보안성 | 편의성 | 복구 용이성 |
|---|---|---|---|
| 로컬 직접 실행 | 낮음 전체 시스템 노출 | 높음 | 어려움 |
| Dev Container + 방화벽 | 높음 프로세스 격리 | 보통 | 쉬움 |
| 완전 격리 VM | 매우 높음 하드웨어 격리 | 낮음 | 복잡 |
참고: 성능 영향은 개발자의 하드웨어 환경, 프로젝트 규모, 사용 패턴에 따라 개인차가 클 수 있습니다.
모범 사례
일상적인 사용 지침
프로젝트 시작 전
- 최신 커밋 상태 확인
- 중요 파일 백업 확인
- 컨테이너 환경 상태 점검
작업 중
- 정기적인 Git 커밋
- AI 제안 사항 검토 후 적용
- 의심스러운 명령어 실행 전 확인
작업 완료 후
- 변경 사항 최종 검토
- 테스트 실행 및 검증
- 원격 저장소에 Push
나가며
AI 코딩 도구의 혁신적인 기능을 안전하게 활용하기 위해서는 적절한 격리 환경이 필수입니다. Dev Container 기반 접근법은 보안과 편의성 사이의 최적 균형점을 제공하며, 현대적인 개발 워크플로우에 자연스럽게 통합됩니다.
조직에서 AI 도구 도입을 고려할 때 다음 원칙을 준수하기를 권장합니다.
- 격리된 환경에서의 작업: 민감한 데이터와 AI 도구 분리
- 지속적인 백업: Git을 통한 정기적 상태 저장
- 모니터링 체계: 이상 행동 탐지 및 대응 방안 수립
- 팀 교육: AI 도구의 한계와 위험성에 대한 인식 공유
이러한 접근을 통해 AI의 강력함을 누리면서도 조직의 보안과 안정성을 동시에 확보할 수 있습니다.
이 글은 NHN Cloud의 AI 보안 강화 노력의 일환으로 작성되었습니다. 긴 글을 읽어 주셔서 감사합니다. 🙂
참고 문헌
• Claud Docs, 개발 컨테이너, https://docs.claude.com/ko/docs/claude-code/devcontainer • Visual Studio Code, Developing inside a Container, https://code.visualstudio.com/docs/devcontainers/containers • Claude Code GitHub Repository, https://github.com/anthropics/claude-code • Development Containers, https://containers.dev/

