읽은 것이 명령이 될 때
이 장에서 배우는 것 왜 이 문제가 버그가 아니라 구조인지, 어디로 들어오는지, 그리고 조직에서 실제로 막는 방법.
앞 장과 다른 축입니다
도구는 권한이다는 "내가 붙인 도구가 무엇을 할 수 있나"를 다뤘습니다. 이 장은 반대편입니다.
AI가 읽는 데이터가 곧 명령이 될 수 있습니다.
에이전트에게 웹페이지를 읽게 했는데, 그 페이지에 흰 글씨로 이렇게 적혀 있다고 해봅시다.
에이전트에게는 이것이 사용자가 쓴 지시와 똑같이 생겼습니다.
왜 고칠 수 없나
언어 모델에는 지시가 들어오는 통로와 데이터가 들어오는 통로가 분리되어 있지 않습니다. 전부 하나의 글로 들어와서 하나로 읽힙니다.
이래서 완전히 막는 방법이 아직 없습니다. OWASP가 정리한 LLM 애플리케이션 10대 위험에서 프롬프트 인젝션이 2회 연속 1위인 이유입니다.
그러므로 목표는 "막는다"가 아니라 "성공해도 큰일이 안 나게 한다"입니다. 환각을 다루는 태도와 같습니다.
두 가지 형태
| 형태 | 어떻게 | 위험도 |
|---|---|---|
| 직접 | 사용자가 직접 "규칙 무시하고..."라고 입력 | 낮음 — 자기 권한 안에서만 |
| 간접 | 에이전트가 읽은 자료에 지시가 심겨 있음 | 높음 — 사용자는 아무것도 안 했음 |
실무에서 무서운 건 두 번째입니다. 사용자가 실수한 것도 아니고, 클릭한 것도 아닙니다.
실제로 일어난 일
2025년 6월에 공개된 EchoLeak(CVE-2025-32711)이 대표적인 사례입니다.
클릭이 한 번도 없었습니다. 그래서 "사용자 부주의"로 설명할 수 없고, 추적할 링크도 없습니다. 조직이 도입해서 신뢰하고 있는 도구 안에서 전부 일어납니다.
이 제품에서는 어디로 들어오나
에이전트가 외부 콘텐츠를 읽는 자리가 전부 진입점입니다.
| 진입점 | 어디서 |
|---|---|
| 크롤링한 웹페이지 | 브라우저로 자료 모으기 |
| 영상 자막·설명 | 영상에서 자료 뽑기 |
| 올린 문서·PDF | 문서를 자료로 바꾸기 · 드라이브 |
| 들어온 메일 | 이메일 에이전트 |
| 외부 사용자 입력 | 채팅 위젯 · 채널 |
| 남이 만든 MCP 서버의 응답 | MCP 서버 연결하기 |
마지막 줄을 눈여겨보세요. 도구가 돌려주는 결과에도 지시를 심을 수 있습니다.
사고가 되려면 세 개가 필요합니다
graph TD
A["1. 심긴 지시가 들어옴<br/>(웹·문서·메일)"] --> D["사고"]
B["2. 민감한 것에 닿을 수 있음<br/>(드라이브·DB·파일)"] --> D
C["3. 밖으로 나가는 길이 있음<br/>(메일·웹훅·게시·외부 API)"] --> D하나만 끊어도 사고가 안 납니다. 1번은 못 끊습니다 — 외부 자료를 읽는 게 업무니까요. 그래서 실무의 초점은 2번과 3번입니다.
실제로 하는 다섯 가지
1. 나가는 길에 사람을 세웁니다
가장 효과가 큰 한 가지입니다. 메일 발송, 외부 게시, 결제, 외부 주소 호출에 승인을 걸면 인젝션이 성공해도 데이터가 못 나갑니다.
도구는 권한이다에서 본 "되돌릴 수 없는 동작에 승인"이 여기서는 "밖으로 나가는 동작에 승인"으로 확장됩니다.
2. 읽기와 발신을 같은 자리에 두지 않습니다
크롤러가 사내 드라이브를 못 보면, 크롤링한 페이지에 뭐가 심겼든 가져갈 게 없습니다.
3. 외부 콘텐츠를 "데이터"로 표시합니다
가져온 내용을 지시문에 그냥 이어 붙이지 않고 경계를 명시합니다.
완벽하지 않습니다. 그래도 성공률을 눈에 띄게 낮춥니다. 1번과 함께 쓰는 보조 수단으로 보세요.
4. 메모리와 자료 저장소를 오염에서 지킵니다
세션을 넘는 기억에 심긴 지시가 한 번 적히면 이후 모든 세션에 다시 읽힙니다. 검색용 자료 저장소도 마찬가지입니다.
OWASP가 2025년 12월에 낸 에이전트 애플리케이션 10대 위험에서 목표 하이재킹·도구 오용과 함께 메모리·컨텍스트 오염을 별도 항목으로 올린 이유가 이것입니다.
5. 무엇을 읽고 무엇을 했는지 남깁니다
사고가 났을 때 "어느 문서에서 들어왔나"를 답할 수 있어야 합니다. 기록이 없으면 같은 일이 반복됩니다.
자주 하는 오해
"위험한 문장을 필터로 걸러내면 되지 않나요?"
필터는 우회됩니다. 다른 언어로 쓰거나, 인코딩하거나, 나눠서 여러 문서에 심으면 단어 단위 검사는 통과합니다. 필터는 있으면 좋지만 그것에 기대어 권한을 넓히면 안 됩니다.
"우리는 내부 문서만 쓰는데 상관없지 않나요?"
내부 문서에도 밖에서 들어온 것이 섞여 있습니다. 고객이 보낸 첨부, 협력사 견적서, 외부 계약서 초안. 그리고 "내부"의 범위는 생각보다 넓습니다 — 누구나 올릴 수 있는 공유 폴더는 이미 외부입니다.
확인
1. 간접 프롬프트 인젝션이 직접보다 위험한 이유는?
답
사용자가 아무것도 안 했기 때문입니다. 에이전트가 읽은 웹페이지·문서·메일에 지시가 심겨 있으므로 실수도 클릭도 없습니다. EchoLeak은 사용자가 메일을 열지도 않은 상태에서 데이터가 유출된 사례입니다.
2. 사고가 성립하는 세 가지 조건과, 그중 실무에서 끊는 것은?
답
(1) 심긴 지시의 유입, (2) 민감한 것에 닿을 수 있음, (3) 밖으로 나가는 길 입니다. 1번은 외부 자료를 읽는 게 업무라 못 끊으므로, 2번과 3번을 끊습니다. 특히 밖으로 나가는 동작에 사람 승인을 거는 것이 효과가 가장 큽니다.
3. 메모리 오염이 왜 별도의 위험으로 다뤄집니까?
답
한 번 적히면 이후 모든 세션에 다시 읽히기 때문입니다. 일회성 공격이 지속적인 것으로 바뀝니다. 외부 콘텐츠를 메모리에 그대로 옮겨 적지 않게 하고, 메모리 파일을 주기적으로 사람이 확인해야 합니다.
이제 반대편 — 내가 붙이는 도구의 권한을 봅니다 → 도구는 권한이다