에이전트를 맹신하지 마세요: 승인을 특정 도구 호출에 귀속시키세요
대부분의 에이전트 시스템은 파일 쓰기나 송금과 같은 위험한 동작을 단순한 승인 절차로 보호합니다.
보통 이 승인은 시스템 상태 내의 불리언(boolean) 플래그로 처리됩니다.
예: approved: true.
이것은 실수입니다. 불리언 방식은 공격자가 악용할 수 있는 세 가지 결함이 있습니다:
- 전환(Flip): 공격자가 프롬프트 인젝션이나 코드 결함을 통해 상태를 false에서 true로 변경합니다.
- 재사용(Replay): "파일 읽기"와 같은 안전한 명령을 승인합니다. 시스템은 "true"를 확인하고 "데이터베이스 삭제"와 같은 두 번째의 위험한 명령을 허용합니다.
- 인자 드리프트(Argument Drift): "$10 송금"을 승인합니다. 공격자가 실행 직전에 금액을 $10,000로 변경합니다. 플래그는 여전히 "true"입니다.
문제는 승인을 전체 세션의 속성으로 모델링하고 있다는 점입니다. 승인은 반드시 특정 호출 하나에 대한 증거여야 합니다.
해결 방법:
사람이 호출을 승인할 때 보안 태그를 생성하십시오. 이 태그는 다음 네 가지 요소를 고정해야 합니다:
- 고유한 도구 호출 ID.
- 정확한 인자(arguments)의 해시값.
- 사용자 신원.
- 만료 시간.
실행되는 바로 그 순간에 이 태그를 검증하십시오. 시스템만 알고 있는 비밀 키를 사용하십시오.
구현 시 다음 규칙을 따르십시오:
- 정규화(Canonicalization) 사용: 승인자와 실행자 모두 정확히 동일한 바이트를 해싱해야 합니다. 숫자와 키가 일치하도록 RFC 8785를 사용하십시오.
- 페일 클로즈(Fail Closed): 태그가 누락되었거나, 만료되었거나, 잘못된 경우 특정 "승인되지 않음(not approved)" 에러를 반환하십시오. 이를 일반적인 도구 결과로 취급하지 마십시오.
- 기본 거부(Deny by Default): 명시적 승인이 필요한 도구만 허용하십시오. 그 외의 모든 것은 거부하십시오.
- 재사용 처리(Handle Replays): Temporal과 같은 엔진을 사용하는 경우, 비밀 키가 결정론적(deterministic)인지 확인하십시오. 시스템 재시작 후 키가 변경되면 기존의 모든 승인이 실패하게 됩니다.
권한 부여(Authorization)는 떠다니는 상태의 조각이 되어서는 안 됩니다. 그것은 반드시 다음과 같은 사실을 증명하는 결합된 봉투(bound envelope)여야 합니다: "이 특정 인물이 이 특정 시간까지 이 특정 도구에 대해 이 특정 인자들을 승인했다."
불리언 사용을 중단하십시오. 그것은 단순화가 아니라 버그입니다.
선택 사항 학습 커뮤니티: https://t.me/GyaanSetuAi