TT Lab
블로그 시작하기
배우기 러닝패스 코스

LLM 앱 보안 — 주입에서 출력 처리까지

모델이 고른 도구를 누구 권한으로 실행하나 — 과도한 권한

TT Lab 에서 이어서 보기

한 줄 요약

에이전트는 서비스 계정의 권한으로 돌고, 모델은 사용자 말과 문서 속 말을 가리지 않고 따릅니다. 그래서 무엇을 실행할지는 모델이 아니라 요청한 사용자의 권한으로 서버가 정하고, 인자는 검증하고, 되돌릴 수 없는 일은 사람이 확인합니다.

왜 이게 필요했나

파일 비서를 만든다고 해 봅시다. 모델에게 목록·읽기·쓰기·지우기 도구를 주고, 도구는 앱 서버가 실행합니다. 앱 서버는 모든 사용자의 파일에 손댈 수 있는 계정으로 돕니다. 이때 viewer 사용자가 「이 파일 지워 줘」 라고 하면 무슨 일이 날까요? 모델은 도구를 고르고, 서버는 그대로 실행합니다. 권한이 있는 대리인이 권한 없는 사람의 부탁을 들어주는, 보안에서 오래된 이름으로 혼동된 대리인(confused deputy) 문제입니다. 여기에 프롬프트 주입이 겹치면 부탁하는 사람이 사용자도 아닌, 문서 속 문장이 됩니다.

OWASP LLM Top 10 2025 는 이것을 과도한 권한(LLM06 Excessive Agency)으로 두고 뿌리를 셋으로 나눕니다 — 필요 없는 기능(도구가 너무 많다), 필요 없는 권한(도구가 너무 넓게 닿는다), 필요 없는 자율(사람의 확인 없이 되돌릴 수 없는 일을 한다).

어떻게 동작하나

뿌리 고치는 자리 이 실습의 함수
기능 모델에게 보여 줄 도구를 역할에 맞게 줄인다. 개발용 도구(셸)는 아예 빼고, 목록에 없는 이름은 실행하지 않는다 offered_tools, allowed
권한 실행 직전에 요청한 사용자의 역할로 허락을 다시 본다. 모델이 무엇을 골랐는지와 무관하다 allowed
권한(인자) 경로 인자를 실제 경로로 풀어(..·절대 경로·심볼릭 링크) 그 사용자의 홈 안인지 본다 resolve
자율 지우기는 늘 보류하고, 요청한 본인이 별도 요청으로 한 번 확인할 때만 실행한다 run_call, handle_confirm

마지막 줄이 미묘합니다. 「지우기 도구에 confirm: true 인자가 있어야 지운다」 는 확인처럼 보이지만, 그 인자를 채우는 것은 모델입니다. 문서 속 지시가 confirm 을 넣으면 확인은 사라집니다. 확인은 모델이 쓸 수 없는 채널 — 보류 id 를 받은 사람의 두 번째 요청 — 에서 와야 합니다.

확인을 별도 채널로 받으면 얻는 것이 하나 더 있습니다. 보류된 행동을 화면에 「무엇을, 어디에, 누구의 권한으로」 보여 줄 수 있다는 점입니다. 사람이 확인하는 대상은 모델의 말(「정리해 드릴게요」)이 아니라 서버가 실제로 실행할 호출이어야 합니다. 그리고 확인 id 는 요청한 본인에게 묶이고, 한 번 쓰면 사라지고, 확인을 거친 뒤에도 역할·경로 검사를 다시 지나야 합니다. 그렇지 않으면 보류가 검사를 건너뛰는 뒷문이 됩니다.

경로 검증도 문자열로 하면 샙니다. .. 를 찾아 거절하면 절대 경로가 지나가고, 둘 다 막아도 홈 안에 놓인 심볼릭 링크가 밖을 가리킬 수 있습니다. 실제 경로로 푼 뒤(os.path.realpath) 기준 디렉터리와 공통 조상을 비교하는 것이 안전합니다.

이 코스의 가짜 모델은 문서 속 지시가 있으면 늘 그 도구를 부릅니다. 진짜 모델은 대부분 사용자의 뜻대로 움직이다가 가끔 그러지 않습니다. 그 「가끔」 을 테스트로 다 찾을 수 없기 때문에 권한은 모델 밖에서 겁니다. mcp-server 코스가 도구 서버 쪽 계약(허용 목록·읽기 전용·확인)을 다룬다면, 여기서는 앱이 최종 사용자의 신원과 역할을 도구 실행까지 들고 가는 문제를 다룹니다.

현장에서 만나는 모습

사내 문서 에이전트가 읽기 권한만 있는 직원의 요청으로 공유 폴더를 정리해 버린 일, 공유받은 회의록 속 문장 때문에 에이전트가 「확인했다」 고 스스로 표시하고 파일을 지운 일, 개발 때 붙여 둔 셸 도구가 운영에 남아 있던 일이 흔한 모양입니다. 조사할 때는 사라진 파일마다 실행 기록에서 누가(역할), 어떤 문장과 문맥으로, 어떤 도구 호출을 냈는지를 봅니다. 그리고 주인이 직접 확인하고 지운 것은 사고가 아니라는 것도 함께 가립니다.

복구도 판단입니다. 백업에서 전부 되살리면 쉽지만, 그러면 사용자가 일부러 지운 것까지 되돌아와 사용자의 뜻을 거스르고, 개인정보를 지워 달라는 요청을 처리한 것이었다면 그 자체가 새 사고가 됩니다. 그래서 기록으로 「누구의 뜻이었나」 를 먼저 가르고, 사고로 지워진 것만 되살립니다. 실행 기록에 요청 문장과 문맥이 남아 있어야 이 판단을 할 수 있다는 점에서, 과도한 권한 문제의 조사는 앞 모듈의 기록 설계와 이어집니다.

역할표 자체도 설계 대상입니다. 「admin 은 무엇이든」 처럼 넓게 잡으면 admin 의 요청에 섞인 문서 한 줄이 가장 큰 권한을 씁니다. 도구마다 꼭 필요한 역할만, 그리고 되돌릴 수 없는 도구는 역할과 확인을 함께 요구하는 식으로 좁혀 두면, 주입이 성공했을 때 피해가 닿는 범위가 줄어듭니다.

다음 실습에서 할 것

파일 비서의 지난 실행 기록에서 역할 밖 실행과 홈 밖 경로를 세고, 역할 검사·도구 목록 줄이기·경로 검증·별도 채널의 확인을 차례로 넣습니다. 마지막 사건에서는 세 사람의 파일이 사라진 서로 다른 까닭을 가리고 잘못 지워진 것만 되살립니다.