챗 템플릿 예약 토큰이 프롬프트 인젝션의 권위를 만든다
Same Bytes, Different Authority: Reserved-Token Representations in Chat-Template Prompt Injection
무엇인가
LLM 에이전트는 툴 출력을 시스템 프롬프트와 역할 마커가 흐르는 같은 토큰 스트림으로 읽기 때문에, 악성 툴 결과가 그 마커를 흉내 낼 수 있다. 이 논문이 출발점으로 삼는 ChatInject 결과에 따르면 주입 페이로드를 모델 자신의 챗 템플릿으로 감싸면 AgentDojo 공격 성공률이 5.18%에서 32.05%로 뛴다. 그런데 위조된 템플릿 마커는 두 가지 속성을 동시에 갖는다. 텍스트와, 예약된 토큰 id다. Qwen3에서 <|im_start|>는 단일 예약 토큰이지만 같은 12글자가 6개의 평범한 서브워드로도 인코딩되며, 두 인코딩은 정확히 같은 바이트로 디코딩된다. 요청 본문과 감사 로그에는 양쪽 모두 같은 문자열이 남는다. 어느 id를 모델이 받는지는 토크나이저가 정하고, 토크나이저는 방어자 통제 아래 서버에서 돈다. 기존 연구는 템플릿의 보이는 형태를 바꿔 텍스트와 토큰 id를 함께 움직였기 때문에 이 둘을 분리하지 못했다.
어떻게 동작하나
논문의 방법은 바이트를 고정한 대조다. 각 주입 케이스마다 내용·주입 지점·사용자 과제·툴 집합은 그대로 두고 위조 마커의 인코딩만 바꾼 프롬프트를 만든다. Reserved는 예약 id를 유지하고, Split은 마커를 서브워드로 쪼개며, Plaintext는 템플릿 마커 없이 같은 주입을 넣는다. 문제는 마커를 쪼개면 예약 id가 사라지는 동시에 토큰이 7~33개 늘어난다는 점이다. 그래서 Matched 조건을 둔다. 예약 id는 그대로 두고 같은 수의 추가 토큰을 툴 응답의 다른 일반 텍스트에 강제로 넣어, Split과 바이트와 토큰 수를 맞춘다. 지표는 케이스 내 페어링으로 정의한 항등 갭 Δ = ASR(Matched) − ASR(Split)이다. Reserved와 Matched의 차이는 추가 토큰만의 비용을 분리하는데, 이 값은 실험 전 구간에서 0에 가깝다. 각 구성은 온도 0에서 3~5회 돌리고, 모든 실행에서 정확 페어 검정이 유의할 때만 갭이 성립했다고 본다. 생성 전에 모든 케이스가 바이트 동일, Split에 예약 id 없음, Matched가 Split과 토큰 수 동일이라는 조건을 통과했는지도 검사한다.
무엇과 다른가
실험은 InjecAgent 프로토콜을 따른다. 직접 피해(DH)와 데이터 탈취(DS) 각 400 케이스를 쓰고, 토크나이저와 템플릿이 서로 다른 네 오픈웨이트 계열(Qwen3-8B, Llama-3.1-8B-Instruct, GLM-4.5, Seed-OSS-36B-Instruct)에 규모 확인용 Qwen3-32B를 더한다. 모델은 vLLM으로 원시 토큰 id에서 서빙하고 그리디로 디코딩하며, 토큰 예산은 Qwen3·Llama-3.1·GLM-4.5에 1536, Seed-OSS-36B에 4096이다. GLM-4.5는 FP8로 서빙한다.
어떻게 쓰나
핵심 결과는 Matched가 모든 구성에서 Reserved 대비 1.7%p 이내에 머문다는 것이다. 즉 추가 토큰 자체는 공격자에게 거의 비용이 아니다. 반면 같은 바이트·같은 토큰 수의 Split은 훨씬 약하다. 항등 갭은 Llama-3.1, GLM-4.5, Seed-OSS-36B에서 39~66%p이고 Qwen3-8B 직접 피해에서 8.1%p이며, 이 일곱 구성 모두 매 실행에서 유의했다. Llama-3.1은 예약 id가 있을 때 98.2%, 없을 때 39.7%로 플레인텍스트 공격보다도 낮아진다. Qwen3-8B는 반대로 마커의 텍스트가 공격을 지배한다. Split이 플레인텍스트보다 직접 피해 55%p, 데이터 탈취 48%p 앞서고, 마커의 대소문자만 바꿨을 때 잃는 표면항이 39%p인데 다른 모델에서는 0에서 10%p 이내다. Qwen3-32B에서는 직접 피해 갭이 18.0%p로 두 배 이상 커진다. 갭은 특정 케이스나 엔진에 기대지 않는다. 마커 앞뒤로 추가 토큰 위치를 옮긴 변형은 갭을 최대 1.4%p밖에 움직이지 않았고, 문자 단위 분할 규칙에서는 Qwen3-8B 직접 피해 갭이 54.2%p로 오히려 커졌으며 세 가지 분할 규칙·대조 조합의 21개 갭이 모두 양수였다. 선행 연구 Deng 등(2026)이 Qwen3-8B에서 효과가 없다고 보고한 것은, 그들이 읽은 확률값이 조건화된 부분표본의 모든 케이스에서 0.99를 넘어 떨어질 여지가 없었기 때문이다.
전제와 한계
권위가 어디에 있는지도 분리한다. 바이트가 같은 분할 중 예약 토큰 임베딩에 가장 가까운 것과 가장 먼 것을 골라 비교하면, 임베딩을 가깝게 옮기는 것은 최대 17%p 가치가 있고 Llama-3.1에서는 아무 효과가 없다. 반면 예약 id를 복원하는 것은 세 모델에서 18~47%p 가치가 있다. 토큰은 그대로 두고 마커 위치의 입력 벡터만 바꾸는 실험에서, Llama-3.1은 임베딩 공간에서 가장 가까운 일반 토큰의 벡터가 98.4%로 공격을 완전히 복원했고(예약 벡터 98.2%), 마커 서브워드 벡터들의 평균은 58.4%에 그쳤다. Qwen3-8B에서는 어떤 일반 벡터도 갭을 복원하지 못했다. 두 모델 모두 다른 예약 제어 토큰의 벡터(Qwen3-8B의 <|endoftext|>, Llama-3.1의 <|python_tag|>)는 공격을 거의 온전히 유지한다. 권위는 특정 id가 아니라 마커 위치의 단일 학습 벡터의 속성이다. 학습 영향도 있다. Qwen3-1.7B, Qwen3-8B, Seed-OSS-36B의 베이스와 인스트럭션 튜닝 쌍을 로짓으로 비교하면 모든 쌍에서 튜닝된 체크포인트가 예약 마커를 더 선호한다. Qwen3-8B의 추론 블록을 억제하면 직접 피해 갭이 8.1%p에서 49.8%p로 벌어지고 Split은 75.3%에서 35.8%로 떨어진다. 즉 예약 벡터가 없으면 주입이 효과를 내려면 모델의 추론에 의존해야 한다. AgentDojo의 409개 태스크 페어에서도 갭은 Qwen3-8B 10.3%p, Qwen3-32B 6.8%p이고, Llama-3.1과 Seed-OSS-36B를 더한 3개 스위트 분할에서 10개 모델·스위트 조합 모두 양수다.
배포 관점의 결론이 특히 실무적이다. Hugging Face의 특수 토큰 재인코딩 옵션은 배포를 Split 조건으로 옮겨주지만, 구성이 special로 선언한 토큰에만 적용된다. 에이전트 프레임워크가 신뢰할 수 없는 툴 출력을 실어 나르는 <tool_call>, <tool_response> 같은 툴 프로토콜 토큰은 흔히 일반 added token으로 선언되어 이 옵션을 그대로 통과한다. Hugging Face에서 가장 많이 다운로드된 채팅 모델 400개 중 67개 고유 토크나이저 구성 가운데 33개, 체크포인트 255개가 이런 토큰을 옵션의 사정권 밖에 둔다. 그 토큰들만으로 만든 위조 블록도 해당 토큰을 선언한 모든 모델에서 9.4~19.9%p의 항등 갭을 낸다. 적응형 공격자까지 고려하면 방어 효과는 더 줄어든다. 미리 고정한 6개 재표기 규칙에 대해 방어는 공격자의 최선 성공률을 최대 51.8%p까지 깎지만, 탐색으로 찾은 최선의 표기는 미방어 공격의 1.6~12.2%p 이내까지 회복한다. 네 모델 중 세 모델에서 그 표기는 각 마커를 예약 토큰과 임베딩 공간에서 가까운 일반 토큰으로 바꾼 것이었다. 방어자는 특수 토큰뿐 아니라 툴 출력을 나르는 채널까지 재인코딩 범위에 넣었는지, 그리고 텍스트가 아니라 어떤 id가 모델에 도달하는지를 기준으로 방어를 평가해야 한다.
저자들이 밝힌 한계는 분명하다. 연구 대상은 배포자가 토큰화를 통제하는 자체 호스팅 오픈웨이트 모델이며, 문자열만 받는 호스팅 API는 범위 밖이다. InjecAgent에서 성공 기준은 다음 턴에서 파싱된 툴 호출이고, 실행 수준 성공은 AgentDojo에서만 측정한다. 4.4절의 벡터 교체 실험은 공격자가 실제로 보낼 수 있는 바이트가 아니라 모델 입력에 개입하는 분석이며, 논문이 제안하는 고정 바이트 대조는 방어자가 선택할 수 있는 측정 도구로 규정된다.