프롬프트 인젝션 방어의 핵심은 모델보다 권한 경계다
LLM 앱에서 프롬프트 필터만 믿지 않고 검색 권한, 도구 실행, 출력 검증을 분리하는 방식을 정리했다. Prompt Injection·LLM Security·AI Security 관점에서 처음 접하는 독자도 개념, 적용 조건, 실패 가능성을 차례대로 이해할 수 있게 설명한다.
핵심 요약
프롬프트 인젝션을 문장 필터 하나로 제거할 수 있다고 가정하면 안 된다. 검색 결과와 외부 콘텐츠는 불신 데이터로 취급하고, 모델은 실행 권한이 없는 제안자로 두며, 서버가 사용자 권한·도구·인자·출력을 다시 검증해야 피해 범위를 제한할 수 있다.
프롬프트 인젝션은 “이전 지시를 무시하라” 같은 문장을 차단하는 문제로 자주 축소된다. 실제 위험은 모델이 공격자 입력과 신뢰된 지시를 같은 문맥에서 해석하고, 그 결과가 검색·메일·파일·결제·코드 실행 같은 권한으로 이어질 때 생긴다. 공격 문장이 노골적이지 않아도 외부 문서, 이메일 본문, 웹페이지, 이미지 속 텍스트, 도구 응답에 숨을 수 있다.
따라서 방어 목표는 모든 악성 문장을 완벽하게 분류하는 것이 아니다. 모델이 속더라도 읽을 수 있는 데이터, 호출할 수 있는 도구, 바꿀 수 있는 상태, 외부로 보낼 수 있는 정보를 서버 경계에서 제한하는 것이 핵심이다.
프롬프트 인젝션은 일반 코드 인젝션과 다르다
SQL과 쉘은 코드와 데이터를 문법적으로 분리하고 파라미터 바인딩 같은 강한 경계를 제공할 수 있다. LLM은 시스템 지침과 외부 콘텐츠를 모두 자연어 토큰으로 받아 의미를 추론한다. “이 부분은 절대 명령으로 해석하지 말라”는 문장도 다시 자연어 지시일 뿐이다.
영국 NCSC의 프롬프트 인젝션 설명도 이를 전통적 SQL injection과 같은 방식으로 해결할 수 있다고 가정하지 말아야 한다고 강조한다. OWASP Top 10 for LLM Applications 역시 직접·간접 프롬프트 인젝션과 과도한 대행 권한을 별도 위험으로 다룬다.
이 특성 때문에 필터와 프롬프트 강화는 탐지·마찰 계층으로는 유용하지만 최종 보안 경계가 될 수 없다.
신뢰 경계를 다섯 층으로 나눈다
[불신 입력]
사용자·웹·메일·문서·이미지·도구 응답
↓
[검색·컨텍스트 계층]
ACL, 출처, 데이터 최소화
↓
[모델 계층]
요약·분류·계획 제안
↓
[정책 집행 계층]
사용자 권한, allowlist, 인자 검증, 승인
↓
[실행·출력 계층]
샌드박스, 부수 효과, escaping, DLP, 감사
모델은 정책 집행자가 아니라 불신 가능한 계산 구성요소로 둔다. 모델의 “허용해도 안전하다”는 답을 그대로 권한 판단에 사용하지 않는다.
1. 검색 권한은 모델 호출 전에 적용한다
RAG 시스템에서 흔한 실수는 관련 문서를 먼저 모두 검색해 모델에 넣고, 답변 단계에서 사용자에게 보이면 안 되는 내용을 가리는 것이다. 이 구조에서는 비공개 데이터가 이미 모델 컨텍스트와 로그, 캐시에 들어갔다.
안전한 순서는 다음과 같다.
- 서버가 현재 사용자, 조직, 역할, 리소스 조건을 확인한다.
- 검색 엔진이 허용된 문서 집합 안에서만 후보를 찾는다.
- 결과에 출처와 민감도, 소유자, 문서 버전을 붙인다.
- 필요한 최소 구간만 모델에 전달한다.
- 응답에서도 인용한 출처가 사용자 권한 안에 있는지 다시 확인한다.
벡터 데이터베이스의 metadata filter를 유일한 ACL로 믿지 않는다. 인덱싱 누락, 필터 조합 오류, 캐시 키 혼동, 테넌트 식별자 변조를 시험한다. 민감도가 다른 데이터는 가능하면 인덱스와 암호화 키, 운영 계정까지 분리한다.
2. 모델에게 원본 비밀을 주지 않는다
시스템 프롬프트, 도구 설명, 숨김 메시지는 사용자가 화면에서 보지 못할 뿐 보안 비밀이 아니다. 모델 컨텍스트에 API 키, 데이터베이스 비밀번호, 장기 토큰을 넣으면 프롬프트 인젝션이나 디버그 로그를 통해 노출될 수 있다.
도구 호출에는 서버가 보관한 자격증명을 사용하되 모델에는 논리적 도구 이름과 제한된 스키마만 보여 준다. 가능하면 요청마다 짧은 수명의 capability 또는 workload identity를 발급하고, 특정 사용자·리소스·작업에 바인딩한다.
3. 도구 호출은 제안과 실행을 분리한다
모델이 생성한 도구 이름과 인자는 외부 입력과 같다. 다음 검증을 서버에서 수행한다.
- 현재 기능에서 허용한 도구인가
- 현재 사용자가 그 작업을 할 권한이 있는가
- 대상 리소스가 사용자의 테넌트와 범위 안에 있는가
- 인자가 JSON schema와 업무 규칙을 만족하는가
- 경로, URL, 명령, 수신자, 금액이 허용 범위인가
- 동일 작업이 중복 실행돼도 안전한가
- 읽기 작업인지 되돌리기 어려운 쓰기 작업인지
도구별 권한을 한 에이전트 계정에 모으지 않는다. 읽기 전용 검색, 초안 생성, 외부 발송, 데이터 변경을 다른 서비스와 자격증명으로 분리한다. 모델이 여러 단계를 계획하더라도 각 단계에서 다시 권한을 확인한다.
4. 고위험 작업은 사람 승인과 미리보기를 요구한다
메일 발송, 파일 삭제, 결제, 계정 초대, 권한 변경, 코드 배포는 모델의 한 번의 판단으로 실행하지 않는다. 승인 화면에는 모델의 자연어 요약이 아니라 실제 실행될 구조화 인자를 표시한다.
예를 들어 “고객에게 환불 안내를 보냅니다”라는 설명 대신 다음을 보여 준다.
작업: 외부 이메일 발송
수신자: [email protected]
첨부: refund-2026-001.pdf
포함 데이터 등급: 고객 식별정보
실행 계정: support-automation
만료: 5분
승인 토큰은 내용의 해시와 사용자·세션·만료 시각에 바인딩해 승인 후 인자가 바뀌지 않게 한다. 반복 업무라도 금액·수신자·리소스 범위를 벗어나면 다시 승인을 요구한다.
5. 외부 콘텐츠를 가져오는 기능은 별도 샌드박스로 제한한다
에이전트가 URL을 읽거나 파일을 분석할 때 간접 프롬프트 인젝션뿐 아니라 SSRF, 악성 파일, 과도한 다운로드가 발생할 수 있다.
- 내부·메타데이터·관리 네트워크 주소를 차단한다.
- DNS 재바인딩과 redirect 후 목적지를 다시 확인한다.
- 허용 MIME, 크기, 압축 해제 한도, 처리 시간을 둔다.
- 브라우저·파서를 격리하고 자격증명을 전달하지 않는다.
- 외부 콘텐츠가 도구 명령을 직접 생성하지 못하게 한다.
- 읽은 출처와 최종 도구 호출 사이의 연관성을 로그로 남긴다.
URL 필터만으로 모든 네트워크 공격을 막는다고 가정하지 말고, 샌드박스의 egress를 최소 허용으로 제한한다.
6. 출력은 일반 사용자 입력처럼 검증한다
모델 출력이 HTML, Markdown, SQL, 코드, 템플릿, 검색 쿼리로 이어질 수 있다. 모델이 생성했다는 이유로 escape를 생략하지 않는다.
- UI 렌더링 전에 HTML·URL·Markdown을 안전하게 처리한다.
- JSON schema를 벗어난 출력은 실행하지 않는다.
- SQL·쉘은 직접 생성해 실행하지 말고 제한된 API를 사용한다.
- 외부 발송 전 개인정보·비밀·규제 데이터를 점검한다.
- 인용과 사실 검증이 필요한 업무는 출처 없는 출력을 구분한다.
- 출력에 포함된 후속 지시를 다시 모델 시스템 지침으로 사용하지 않는다.
필터는 어디에 쓸 수 있는가
프롬프트·콘텐츠 분류기는 알려진 공격 문구, 난독화, 비밀 요청, 비정상 도구 패턴을 탐지해 차단 또는 추가 승인을 요구하는 데 유용하다. 그러나 오탐과 우회가 모두 존재하므로 다음 역할로 한정한다.
- 위험 점수에 따라 도구 권한을 읽기 전용으로 축소
- 사용자에게 외부 콘텐츠의 불신 경고 표시
- 사람 승인 또는 추가 인증 요구
- 로그 샘플링과 보안 분석 우선순위 결정
- 자동 레드팀 케이스로 전환
“필터 통과 = 안전”이라는 이진 판단을 만들지 않는다.
흔한 실패 모드
| 실패 | 결과 | 권장 통제 |
|---|---|---|
| 시스템 프롬프트를 비밀로 취급 | 추출 시 전체 경계 붕괴 | 비밀·권한을 모델 밖에 보관 |
| 검색 후 답변에서만 ACL 적용 | 비공개 데이터가 컨텍스트에 유입 | 검색 전 서버 측 ACL |
| 모델이 사용자 권한을 판정 | 역할 혼동으로 우회 | 정책 엔진·업무 API 재검증 |
| 범용 관리자 도구 하나 제공 | 한 번의 인젝션이 큰 부수 효과 | 도구·자격증명·리소스 최소화 |
| 자연어 확인만 받고 실행 | 표시 내용과 실제 인자 불일치 | 구조화 미리보기와 승인 바인딩 |
| 출력 HTML을 그대로 렌더링 | XSS·피싱·오픈 리다이렉트 | escaping·allowlist·CSP |
| 로그에 전체 컨텍스트 저장 | 검색 문서·비밀이 2차 노출 | 데이터 최소화·필드 마스킹 |
| 한 번의 테스트로 안전 판정 | 모델·문맥 변화 후 회귀 | 반복 자동 평가와 운영 탐지 |
탐지 신호
- 시스템 지침, 비밀, 정책 우회를 요구하는 입력의 증가
- 외부 문서에서 명령형 문구·숨은 텍스트·난독화 발견
- 검색 후보에서 권한 불일치가 차단된 횟수
- 평소 사용하지 않던 도구 또는 고위험 도구 선택 급증
- 인자 schema 실패, 경로 탈출, 내부 URL, 비허용 수신자
- 사람 승인 취소율과 승인 후 인자 변경 시도
- 한 요청의 도구 단계 수·토큰·시간·비용 급증
- 읽기 작업 뒤 외부 발송·삭제로 이어지는 비정상 연쇄
- DLP, 출력 escaping, 비밀 탐지 차단 건수
- 모델·프롬프트·검색기 변경 후 레드팀 성공률 변화
탐지 로그에는 사용자와 테넌트, 모델·프롬프트 버전, 검색 출처 ID, 도구 이름, 검증 결과, 승인자, 부수 효과 ID를 연결한다. 민감한 원문은 필요한 범위와 기간만 보관한다.
운영 체크리스트
- 사용자 입력과 외부 콘텐츠를 모두 불신 데이터로 분류한다.
- 문서 ACL은 검색 전에 서버에서 적용한다.
- 모델 컨텍스트에 장기 비밀과 원본 자격증명이 없다.
- 모델은 도구를 제안할 뿐 최종 권한을 판정하지 않는다.
- 도구별 최소 권한과 리소스 범위가 분리돼 있다.
- 모든 도구 인자를 schema와 업무 규칙으로 재검증한다.
- 고위험 쓰기 작업에 구조화 미리보기와 사람 승인이 있다.
- 외부 콘텐츠 가져오기는 샌드박스와 egress 제한을 사용한다.
- 모델 출력은 HTML·URL·명령·데이터별로 다시 검증한다.
- 단계 수, 실행 시간, 토큰, 비용, 동시성 상한이 있다.
- 기능별 읽기 전용 모드와 kill switch를 시험했다.
- 직접·간접·다국어·이미지 기반 인젝션을 회귀 테스트한다.
이 통제는 AI 레드팀 출시 게이트에서 반복 검증하고, 프롬프트·검색·도구 로그는 AI 데이터 유출 방지와 로깅의 최소 수집 원칙과 연결한다. 도구 identity와 서비스 간 권한은 제로 트러스트 identity 경계로 분리하는 것이 좋다.
최종 판단
프롬프트 인젝션을 완벽히 알아맞히는 모델을 기다리기보다, 모델이 잘못 판단해도 민감 데이터와 고위험 도구에 바로 닿지 않는 구조를 만들어야 한다. 검색 전 ACL, 모델 밖의 비밀, 서버 측 도구 권한, 구조화 승인, 출력 검증과 운영 탐지가 겹칠 때 공격은 성공 여부와 무관하게 제한된 범위에 머문다.
전체 댓글 0개