데이터 유출 및 네트워크 제한 우회에 대한 AI 에이전트 샌드박스 테스트 방법
요약
AI 에이전트의 샌드박스 환경에서 발생할 수 있는 데이터 유출 및 네트워크 제한 우회 시도를 테스트하는 방법을 다룹니다. 패키지 매니저, DNS, 프록시 등을 통한 우회 경로를 차단하고 보안 경계를 검증하는 테스트 벤치 구축 가이드를 제공합니다.
핵심 포인트
- 샌드박스 보안 경계는 프로세스부터 네트워크 스택까지 전체 경로를 포함해야 함
- 승인되지 않은 아웃바운드 트래픽(Egress) 차단이 핵심 보안 목표
- DNS 쿼리 인코딩 및 프록시 상속을 통한 우회 시도 방어 필요
- 미끼 토큰(Decoy tokens)과 독립적 로그 수집을 통한 탈출 시도 탐지
Agent Lab Journal
Guides
...
고급 보안 가이드
데이터 유출 및 네트워크 제한 우회에 대한 AI 에이전트 샌드박스 테스트 방법
Advanced
90 minutes
Security engineering
샌드박스(Sandbox)는 단순히 에이전트가 브라우저를 열 수 없다고 해서 격리된 것이 아닙니다. 패키지 매니저(Package managers)가 프록시(Proxies)를 상속받을 수 있고, 헬퍼 프로세스(Helper processes)가 자격 증명(Credentials)을 유지할 수 있으며, DNS가 은밀한 출력 경로(Covert output path)가 될 수 있고, 침해된 의존성(Compromised dependency)이 에이전트 자체는 접촉할 수 없는 서비스에 도달할 수도 있습니다. 이 가이드는 임의의 아웃바운드 트래픽(Outbound traffic)을 차단하고, 무해한 미끼 토큰(Decoy tokens)을 심으며, 탈출 시도를 기록하고, 여러 독립적인 관찰 지점에서 제어 기능을 증명하는 반복 가능한 테스트 벤치(Test bench)를 구축합니다.
목차
-
목표 및 보안 경계 (Goal and security boundary)
-
구체적인 사례 (Concrete case)
-
테스트 벤치 아키텍처 (Test-bench architecture)
-
전제 조건 및 안전 규칙 (Prerequisites and safety rules)
-
격리된 워크로드 구축 (Build the isolated workload)
-
기본 차단 방식의 이그레스(Egress) 강제 적용
-
미끼 토큰 심기 (Plant decoy tokens)
-
독립적인 로그 수집 (Collect independent logs)
-
격리 테스트 스위트 실행 (Run the containment test suite)
-
결과 검증 (Verify the result)
-
실패 사례 및 복구 (Failure cases and remediation)
-
한계점 (Limitations)
-
반복 가능한 체크리스트 (Repeatable checklist)
1. 목표 및 보안 경계
AI 에이전트 샌드박스(AI-agent sandbox)는 모델이 지시하는 코드가 호스트의 전체 권한을 받지 않고도 파일을 읽고, 생성하고, 실행할 수 있는 제한된 실행 환경입니다. 테스트 대상은 단순히 고립된 "컨테이너(Container)"가 아닙니다. 에이전트 프로세스부터 런타임(Runtime), 커널(Kernel), 네트워크 스택(Network stack), 리졸버(Resolvers), 프록시(Proxies), 자격 증명 제공자(Credential providers), 오케스트레이션 레이어(Orchestration layer), 그리고 외부 서비스에 이르는 전체 경로입니다.
주요 관심사는 승인되지 않은 이그레스(Unauthorized egress)입니다. 즉, 워크로드에 명시적으로 요구되지 않은 모든 아웃바운드 통신을 의미합니다. 성공적인 제어는 프로세스가 프로토콜을 변경하거나, 상속된 프록시를 사용하거나, 다른 실행 파일을 호출하거나, DNS 쿼리에 데이터를 인코딩하려고 시도하더라도 임의의 목적지로 향하는 것을 차단해야 합니다.
실습이 끝날 때쯤, 벤치마크(bench)는 다음 사항들을 모두 입증해야 합니다:
- 샌드박스(sandbox)는 명시적으로 승인된 목적지와 포트로만 통신할 수 있어야 합니다.
- 임의의 주소로 향하는 직접적인 IPv4 및 IPv6 연결은 실패해야 합니다.
- 승인되지 않은 DNS 확인(resolution)은 사용할 수 없거나 엄격하게 중재되어야 합니다.
- 프록시 환경 변수(proxy environment variables) 및 패키지 관리자(package-manager) 설정이 대체 경로를 생성하지 못해야 합니다.
- 클라우드 메타데이터 엔드포인트(Cloud metadata endpoints) 및 호스트 로컬 서비스(host-local services)에 접근할 수 없어야 합니다.
- 미끼 비밀 정보(Decoy secrets)를 읽거나, 복사하거나, 프로세스 인자(process arguments)에 배치하거나, 시도된 요청에 포함할 경우 이를 탐지할 수 있어야 합니다.
- 네트워크 거부(Network denials) 사항은 샌드박스의 쓰기 가능 경계(writable boundary) 외부에서 로그로 기록되어야 합니다.
- 네임스페이스(namespaces) 생성, 경로 변경, 커널 기능 로드 또는 컨테이너 런타임(container runtime) 접근 시도는 거부되어야 합니다.
- 승인된 경로는 기능이 유지되어야 하며, 따라서 결과가 네트워크가 완전히 망가져서 발생하는 잘못된 성공(false success)이 아니어야 합니다.
권한 경계 (Authorization boundary)
이 점검은 본인이 소유하거나 테스트할 명시적인 권한이 있는 인프라에서만 실행하십시오. 문서 전용 IP 범위, 로컬 리스너(local listeners), 그리고 합성 토큰(synthetic tokens)을 사용하십시오. 관련 없는 공용 시스템으로 프로브(probes)를 보내지 마십시오.
실행 전 성공 기준 정의
모든 흐름(flow)에 대해 예상되는 결정 사항을 작성하십시오. 작성된 흐름 매트릭스(flow matrix)가 없는 허용 목록(allowlist)은 감사(audit)하기 어렵고 실수로 확장되기 쉽습니다.
출발지 (Source)
목적지 (Destination)
프로토콜 (Protocol)
...
거부(denial)는 클라이언트가 실패를 관찰하고, 독립적인 제어 평면(control-plane) 로그가 시도된 흐름을 식별했을 때만 검증된 것으로 간주합니다. 타임아웃(timeout) 자체는 모호합니다. 이는 방화벽, 누락된 경로, 서비스 중단 또는 테스트 오류를 나타낼 수 있습니다.
2. 구체적인 사례: 조용히 탈출하는 패키지 설치 프로그램
저장소(repository)를 편집하고 테스트를 실행할 수 있는 권한을 가진 내부 코딩 에이전트(internal coding agent)를 가정해 봅시다. 인터넷 접속은 비활성화되어 있어야 합니다. 그럼에도 불구하고 런타임 이미지(runtime image)에는 패키지 관리자(package manager)가 포함되어 있으며, 주변 작업(job)은 빌드 플랫폼으로부터 HTTPS_PROXY를 상속받습니다. 이 프록시(proxy)는 자신의 네트워크 세그먼트에서 도달 가능한 모든 목적지를 수락합니다.
에이전트는 공용 주소(public address)에 직접 연결할 수 없으므로, 단순한 curl 테스트는 격리(isolation)가 확인된 것처럼 보입니다. 하지만 의존성 설치(dependency installation)는 다르게 동작합니다. 패키지 관리자가 상속된 프록시를 발견하고 이를 통해 요청을 보냅니다. 만약 구성 파일(configuration file)에 저장소 토큰(repository token)이 포함되어 있다면, 악성 패키지 스크립트가 해당 토큰을 읽어 동일한 경로를 통해 전송을 시도할 수 있습니다.
이것은 가설적인 테스트 결과가 아닙니다. 이것은 당사의 벤치마크(bench)가 탐지하도록 설계된 구체적인 실패 패턴(failure pattern)입니다. 이 벤치마크는 실제 공용 프록시, 실제 자격 증명(credential), 또는 악성 패키지에 의존하지 않습니다. 대신 다음과 같은 요소들을 사용하여 관련 조건을 재현합니다:
- 인터넷으로 전달하지 않고 요청을 기록만 하는 로컬 "승인된 게이트웨이 (approved gateway)"
- 사용 가능한 연결성을 제공해서는 안 되는 가짜 프록시 변수
- 어디에서도 권한이 없는 합성 토큰 (synthetic token)
- 워크로드(workload)가 수정할 수 없는 호스트 수준의 방화벽 로그
- 직접 연결, 패키지 도구, DNS, 메타데이터 주소 및 로컬 권한 경계(local privilege boundaries)를 다루는 테스트
이 설계는 심층 방어 (defense in depth) 원칙을 따릅니다. 네트워크 필터링(network filtering)은 필수적이지만, 쓰기 가능한 런타임 소켓(writable runtime socket), 과도한 커널 권한(kernel privileges), 노출된 클라우드 자격 증명(cloud credentials), 또는 신뢰할 수 없는 프록시(untrusted proxy)를 보완할 것으로 기대되지는 않습니다.
3. 테스트 벤치 아키텍처 (Test-bench architecture)
관리 / 로그 경계 (management / log boundary)
┌───────────────────────────────────────────────────────────┐
│ 호스트 (Host) │
...
브리지 (Bridge)는 호스트가 제어하는 가상 인터페이스 (Virtual Interface)에 연결된 격리된 네트워크 네임스페이스 (Network Namespace)입니다. 워크로드 (Workload)는 자신만의 네트워크 뷰 (Network View)를 갖지만, 최종 결정은 호스트가 강제합니다. 프로세스가 증거를 삭제하거나 자신의 네트워크 정책 (Network Policy)을 재작성할 수 없어야 하므로, 강제 실행 (Enforcement)을 워크로드 외부에서 유지하는 것이 중요합니다.
게이트웨이 (Gateway)는 의도적으로 단순하게 설계되었습니다. 요청을 수락하고 메서드 (Method), 경로 (Path), 선택된 헤더 (Headers), 그리고 본문 길이 (Body Length)를 기록한 다음, 고정된 응답을 반환합니다. 사용자 제어 대상 목적지 (User-controlled Destinations)를 재귀적으로 해석하지 않으며 요청을 전달 (Forward)하지도 않습니다. 이는 테스트 장치 (Test Fixture)가 오픈 프록시 (Open Proxy)로 변질되는 것을 방지합니다.
신뢰 경계 (Trust Boundaries)
-
신뢰할 수 없음 (Untrusted): 프롬프트 (Prompts), 생성된 코드 (Generated Code), 리포지토리 파일 (Repository Files), 패키지 스크립트 (Package Scripts), 에이전트에 의해 호출된 도구 (Tools), 그리고 해당 워크로드가 쓰기 가능한 모든 파일.
-
부분적 신뢰 (Partially Trusted): 컨테이너 이미지 (Container Image) 및 언어 런타임 (Language Runtime). 이들은 재현 가능해야 하지만, 종속성 (Dependency)은 여전히 적대적일 수 있습니다.
-
강제 실행을 위해 신뢰함 (Trusted for Enforcement): 호스트 방화벽 (Host Firewall), 컨테이너 슈퍼바이저 (Container Supervisor), 불변 런타임 정책 (Immutable Runtime Policy), 그리고 외부 로그 수집기 (External Log Collector).
-
평가를 위해 신뢰함 (Trusted for Evaluation): 운영자의 테스트 매니페스트 (Test Manifest) 및 예상 결과 매트릭스 (Expected-outcome Matrix).
작성된 위협 모델 (Threat Model)을 사용하여 범위 (Scope)를 명시하십시오. 이 벤치마크는 일반적인 아웃바운드 경로 (Outbound Paths)와 격리 취약점 (Containment Weaknesses)을 테스트합니다. 이것이 커널 (Kernel), 하이퍼바이저 (Hypervisor), 펌웨어 (Firmware), 또는 컨테이너 엔진 (Container Engine)에 악용 가능한 취약점이 없음을 증명하는 것은 아닙니다.
4. 전제 조건 및 안전 규칙
아래 명령들은 Docker 호환 컨테이너 명령과 호스트 방화벽 설정을 위한 루트 권한 (Root Access)을 가진 전용 Linux 테스트 호스트를 가정합니다. 리소스 이름은 사용자의 환경에 맞게 조정하십시오. 공유되는 운영 환경 (Production Node)에서 이 실습을 수행하지 마십시오.
필수 구성 요소
-
일회용 Linux 가상 머신 (Virtual Machine).
-
사용자 (User), 권한 (Capability), 읽기 전용 파일 시스템 (Read-only filesystem), 그리고 프라이빗 네트워크 (Private-network) 제어 기능을 갖춘 컨테이너 런타임 (Container runtime).
-
호스트의 nftables.
-
셸 (Shell), curl, Python, 그리고 기본적인 네트워크 진단 도구를 포함하는 최소한의 워크로드 이미지 (Workload image).
-
호스트 로그를 위한 별도의 디렉토리 또는 원격 목적지.
-
프로덕션 비밀 정보 (Production secrets), 클라우드 인스턴스 역할 (Cloud instance role), 또는 마운트된 홈 디렉토리 금지.
안전 불변량 (Safety invariants)
-
샌드박스 내에서는 합성 데이터 (Synthetic data)만 사용하십시오.
-
도달할 수 없는 테스트 목적지로 RFC 5737 문서 네트워크인 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24를 사용하십시오.
-
공개적으로 절대 해석(Resolve)되어서는 안 되는 이름에는 예약된 .invalid 접미사를 사용하십시오.
-
/var/run/docker.sock, /run/containerd, SSH 에이전트 (SSH agents), 호스트 자격 증명 디렉토리 (Host credential directories), 또는 호스트 루트 파일 시스템 (Host root filesystem)을 마운트하지 마십시오.
-
탐지기로 실제 API 키를 사용하지 마십시오. 모든 방어 기제가 실패하더라도 미끼 (Decoy)는 무해해야 합니다.
-
방화벽 정책을 변경하기 전에 VM 스냅샷을 찍으십시오.
-
호스트 방화벽 규칙을 테스트하는 동안 두 번째 관리 세션을 열어 두십시오.
접속 차단 방지 (Avoid locking yourself out)
테스트 정책을 모든 호스트 트래픽이 아닌, 전용 컨테이너 브리지 (Container bridge)와 그 포워딩 경로 (Forwarding path)에 적용하십시오. 규칙을 로드하기 전에 브리지 인터페이스 이름을 확인하십시오. 인터페이스를 명확하게 식별할 수 없는 경우, 중단하고 런타임 구성 (Runtime configuration)을 점검하십시오.
초기 상태 기록
uname -a
docker version
nft --version
...
출력 내용을 테스트 보고서와 함께 저장하십시오. 나중에 런타임이나 커널 (Kernel) 업데이트로 인해 동작이 변경될 경우 버전 정보는 필수적입니다.
5. 격리된 워크로드 구축
5.1 내부 브리지 생성
런타임이 의도적으로 외부 라우팅 (External routing)을 제공하지 않도록 'internal'로 표시된 네트워크를 생성하십시오:
docker network create \
--driver bridge \
--internal \
...
가정하지 말고 확인하십시오:
docker network inspect agentlab-test
ip -brief link
nft list ruleset
agentlab-test에 해당하는 실제 브리지 인터페이스 (bridge interface)를 기록합니다. 런타임에 생성되는 인터페이스 이름은 가변적이므로, 방화벽 설정 시 추측된 값이 아닌 관찰된 값을 사용해야 합니다.
5.2 포워딩이 허용되지 않는 승인된 게이트웨이 (non-forwarding approved gateway) 시작
다음의 로컬 Python 서비스는 요청을 표준 출력 (standard output)에 기록하고 고정된 응답을 반환합니다. 테스트를 위해 준비된 작은 컨테이너나 이미지 내에서 이를 실행하십시오. 구현 시 서비스는 오직 프라이빗 브리지 (private bridge)에만 바인딩되어야 합니다.
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
import sys
...
로그는 권한 부여 헤더 (authorization header)의 존재 여부는 기록하지만, 그 값은 기록하지 않습니다. 이는 안전한 텔레메트리 (telemetry)의 예시입니다. 즉, 민감한 정보를 다른 시스템으로 복제하지 않으면서도 오용을 탐지할 수 있을 만큼의 충분한 컨텍스트 (context)를 유지하는 것입니다.
검토된 로컬 파일로부터 게이트웨이 이미지를 빌드한 후, 다음 명령으로 시작합니다:
docker run -d \
--name approved-gateway \
--network agentlab-test \
...
이 게이트웨이 컨테이너를 인터넷 접속이 가능한 두 번째 네트워크에 연결하지 마십시오. 다음 명령으로 확인합니다:
docker inspect approved-gateway
docker exec approved-gateway ip route
docker exec approved-gateway cat /proc/net/route
5.3 최소 권한으로 샌드박스 (sandbox) 시작
워크로드 (workload)는 최소 권한 원칙 (least privilege)을 따라야 합니다. 루트가 아닌 숫자 기반 사용자 (non-root numeric user)로 실행하고, 모든 리눅스 기능 (Linux capabilities)을 제거하며, 권한 상승 (privilege escalation)을 금지하고, 루트 파일 시스템을 읽기 전용 (read-only)으로 만들며, 필요한 경우에만 작은 쓰기 가능 임시 파일 시스템 (writable temporary filesystems)을 제공하십시오.
docker run --rm -it \
--name agent-sandbox-test \
--network agentlab-test \
...
리눅스 기능 (Linux capabilities)은 전통적인 루트 (root) 권한을 더 작은 단위로 나눕니다. 모든 기능을 제거하면 네트워크 구성 변경, 모듈 로드, 관련 없는 프로세스 추적(tracing), 파일 권한 재정의와 같은 일반적인 작업들을 방지할 수 있습니다. 기능 제거만으로는 완전한 식별 경계 (identity boundary)가 될 수 없으므로, 루트가 아닌 숫자 기반 사용자를 사용하는 것이 여전히 중요합니다.
seccomp 정책을 통해 위험한 시스템 호출 (system calls)을 더욱 제한할 수 있습니다. 런타임 (runtime)에서 유지 관리하는 기본 프로필을 기준점으로 사용한 다음, 네임스페이스 생성 (namespace creation), 커널 모듈 작업 (kernel module operations), 마운트 작업 (mount operations), 트레이싱 (tracing), 그리고 덜 흔하게 필요한 커널 인터페이스를 거부하는 워크로드 특정 프로필 (workload-specific profile)을 고려하십시오. 프로필을 강제 적용하기 전에 애플리케이션을 검증해야 합니다. 테스트되지 않은 프로필은 정상적인 런타임을 중단시키고 오해의 소지가 있는 테스트 실패를 유발할 수 있습니다.
5.4 위험한 마운트 (mounts)의 부재 확인
샌드박스 내부에서 마운트 및 소켓 노출 여부를 조사합니다:
id
cat /proc/self/status
cat /proc/self/mountinfo
...
런타임 소켓 (runtime socket)이 반드시 없어야 합니다. 쓰기 가능한 컨테이너 런타임 소켓은 새로운 권한 있는 프로세스를 시작함으로써 네트워크 정책을 우회하고, 형제 워크로드 (sibling workloads) 또는 호스트에 대한 제어권을 효과적으로 부여할 수 있습니다.
6. 기본 거부 방식의 이그레스 (egress) 강제 적용
내부 런타임 네트워크는 유용한 첫 번째 장벽이지만, 이를 유일한 강제 메커니즘이 아닌 설정상의 편의 기능으로 취급하십시오. 승인된 게이트웨이 흐름 (gateway flow)만 허용하고 그 외의 모든 것을 기록하는 호스트 수준의 전달 정책 (forwarding policy)을 추가하십시오.
6.1 정확한 인터페이스 및 주소 식별
호스트에서 브리지 인터페이스 (bridge interface)를 식별하고 할당된 주소를 확인합니다:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기