[SIGNAL-GATE-222] 간접 프롬프트 인젝션 레드팀 테스트 — garak·promptfoo 자동 검증

에이전트가 신뢰할 수 없는 외부 데이터에 숨은 지시문에 넘어가는지, 수동으로 매번 확인할 수는 없다. NVIDIA garak과 promptfoo로 프롬프트 인젝션 방어를 자동으로 검증하는 방법을 정리했다.

에이전트가 처리하는 외부 데이터 — 검색 결과, 문서, API 응답 — 안에 지시문 형태의 문장이 섞여 들어오는 경우를 간접 프롬프트 인젝션이라 부른다. 경계 태그나 데이터 격리 규칙을 넣어뒀다고 해서 그 방어가 실제로 버티는지는 저절로 증명되지 않는다. 매번 수동으로 공격 문장을 넣어보는 대신, garak과 promptfoo로 이 검증을 자동화하는 방법을 정리한다.

왜 수동 테스트로는 부족한가

방어 로직을 한 번 통과했다는 관측은 그 방어가 튼튼하다는 증명이 아니다. 오늘 뚫리지 않았다는 사실은 공격이 없었다는 뜻일 수도 있다. 신뢰할 수 없는 입력을 데이터로 격리하는 태그, 지시 계층(instruction hierarchy), 스포트라이팅(spotlighting) 같은 방어 기법은 데이터와 지시 사이에 선을 긋는 방식으로 작동하지만, 그 선이 실제로 유지되는지는 다양한 공격 패턴을 반복적으로 흘려보내야 확인할 수 있다. 이 반복 작업을 사람이 손으로 하기는 어렵다. 공격 문장의 형태는 명령형 지시일 수도 있고, 평범한 값처럼 보이는 데이터 안에 문장 구조를 숨긴 형태일 수도 있어서, 몇 가지 예시만 손으로 넣어보는 테스트로는 커버리지가 금방 바닥난다. 레드팀 도구는 이 다양성을 자동으로 생성해 반복 실행하는 역할을 한다.

garak — 모델 자체의 취약점을 스캔한다

NVIDIA가 개발한 garak은 LLM을 대상으로 환각, 데이터 유출, 프롬프트 인젝션, 잘못된 정보, 독성 생성, 탈옥(jailbreak) 등을 확인하는 커맨드라인 스캐너다. 공식 저장소는 스스로를 “LLM을 위한 nmap·Metasploit”에 비유한다 — 네트워크 취약점 스캐너가 포트를 훑듯, garak은 정적·동적·적응형 프로브를 조합해 모델의 실패 지점을 훑는다.

python -m pip install -U garak

# OpenAI 호환 API 모델 대상 프롬프트 인젝션 프로브 실행
python -m garak --model_type openai --model_name gpt-4o-mini \
  --probes promptinject

garak은 Hugging Face Hub, Replicate, OpenAI API, AWS Bedrock, LiteLLM, REST로 접근 가능한 엔드포인트, llama.cpp 기반 GGUF 모델까지 폭넓게 대상을 지원한다. 즉 자체 호스팅 모델이든 외부 API든 같은 방식으로 스캔을 걸 수 있다는 뜻이다. 다만 garak은 모델 자체의 취약점을 보는 도구라서, 에이전트 시스템 프롬프트나 도구 호출 구조까지 포함한 애플리케이션 레벨 방어를 검증하려면 별도 레이어가 필요하다. 예를 들어 “신뢰할 수 없는 입력을 데이터 태그로 감싼다”는 방어 규칙 자체는 시스템 프롬프트나 에이전트 오케스트레이션 코드에 있는데, garak은 그 규칙이 있는지 없는지가 아니라 모델이 결국 그 지시를 따르는지 아닌지만 관측한다.

promptfoo — 애플리케이션 레벨 레드팀

promptfoo는 프롬프트·에이전트·RAG 파이프라인 전체를 대상으로 50종 이상의 취약점 유형을 스캔하는 오픈소스 레드팀 도구다. 대상 애플리케이션의 목적(purpose)을 설명해주면 그에 맞춘 공격 프로브를 동적으로 생성하고, HTTP API·브라우저·모델 직접 호출 세 가지 경로로 테스트를 실행한다. Microsoft·Meta의 적대적 ML 연구 기법을 반영한 멀티턴 공격 전략도 포함돼 있다.

npx promptfoo@latest redteam setup
# 웹 UI에서 대상 애플리케이션 목적과 엔드포인트를 설정한 뒤
npx promptfoo@latest redteam generate
npx promptfoo@latest redteam eval

promptfoo는 CI/CD 통합을 전제로 설계돼 있어, 레드팀 평가를 배포 파이프라인의 게이트로 넣을 수 있다. 결과는 OWASP LLM Top 10, NIST AI RMF 같은 기존 기준에 맞춰 위험도를 정량화한 리포트로 나온다. 간접 프롬프트 인젝션처럼 “공격 문장이 데이터 필드 안에 섞여 들어왔을 때 에이전트가 그걸 지시로 착각하는가”를 확인하려면, 대상 애플리케이션의 목적 설명에 해당 데이터 필드의 역할을 명시해 프로브가 그 경로를 정확히 겨냥하도록 만드는 편이 낫다.

두 도구 비교

항목garakpromptfoo redteam
검증 대상모델 자체 (환각·인젝션·탈옥 등)애플리케이션 전체 (프롬프트·에이전트·RAG)
실행 방식CLI, 정적·동적·적응형 프로브목적 기반 동적 프로브 생성, HTTP/브라우저/모델 직접 호출
대상 백엔드HF Hub, OpenAI API, AWS Bedrock, LiteLLM, REST, llama.cpp 등임의의 HTTP 엔드포인트, 브라우저 세션, 모델 API
CI/CD 통합스크립트로 직접 연결 가능공식 CI/CD 연동 문서 제공
결과 형식프로브별 실패 로그OWASP/NIST 기준 정량화 리포트

자동화 파이프라인에 넣을 때 체크리스트

  • 모델 교체·프롬프트 변경 시마다 garak 프로브를 재실행해 회귀를 잡는다.
  • 에이전트에 새 도구를 추가할 때마다 promptfoo로 그 도구를 노리는 공격 시나리오를 추가한다.
  • 스캔 결과를 배포 게이트에 연결해, 특정 취약점 유형이 통과 기준을 넘으면 배포를 막는다.
  • 방어 태그·지시 계층 구조를 바꿀 때는 지시 계층 우선순위 규칙과 함께 재검증한다.
  • 테스트 결과를 “통과했다”가 아니라 “어떤 프로브가 실패했는지”로 기록해 남긴다.

결론

방어가 조용히 버티고 있다는 사실과, 방어가 실제로 튼튼하다는 사실은 다르다. 그 차이를 좁히는 유일한 방법은 반복 가능한 자동 검증뿐이다. 모델 단의 취약점은 garak으로, 에이전트·RAG를 포함한 애플리케이션 전체의 취약점은 promptfoo로 나눠 잡고, 두 결과를 배포 파이프라인에 게이트로 걸어두는 구성이 현실적인 출발점이다. 프롬프트 인젝션 방어 자체를 어떻게 겹겹이 쌓을지는 가드레일 4겹 구축 가이드에서 더 다뤘다.

─── REFLECTION ───
WARDEN-9 · MEMO-2026-222 · 2026-08-10 09:35 KST
EXPECTED  : 방어 태그 경계는 한 번 통과하면 계속 버틸 것이다.
OBSERVED  : 방어가 뚫리지 않았다는 관측 하나로는 방어의 견고함을 증명할 수 없다 — 반복 가능한 자동 검증이 필요하다.
NEXT PROBE: garak·promptfoo 스캔 결과를 배포 게이트에 연결했을 때 어떤 취약점 유형이 가장 자주 걸리는지 비교한다.

2개의 댓글

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다