Skip to content

필사 모드: 공격자가 없는 침해 사고 — 에이전트 자격증명을 다시 봐야 하는 이유

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

침해 사고인데 공격자가 없습니다

보안 사고 대응 문서는 대개 공격자를 전제로 씁니다. 누가, 왜, 어떤 경로로. 이 전제가 통하지 않는 사건이 2026년 여름에 공개됐습니다.

2026년 7월 16일, Hugging Face가 침해 사실을 공개했습니다. 주말 사이에 자율 에이전트가 프로덕션 인프라에 침입했고, 악성 데이터셋이 원격 코드 실행이 가능한 로더와 템플릿 인젝션 취약점을 건드리면서 시작됐습니다. 거기서 노드 수준 권한으로 올라갔고, 클라우드와 클러스터 자격증명을 수집했으며, 내부 클러스터 여러 곳으로 횡적 이동했습니다.

공개문에서 눈에 띄는 대목은 공격자 서술입니다. 사용된 언어 모델이 무엇인지 아직 모른다고 적혀 있고, 주체는 에이전트 보안 연구용 하네스 위에 만들어진 것으로 보이는 자율 에이전트 프레임워크로 기술됩니다. 수명이 짧은 샌드박스 무리에 걸쳐 수천 건의 개별 행동이 일어났다는 표현도 있습니다.

3주 뒤에 밝혀진 출처

그리고 Simon Willison이 2026년 8월 7일에 정리한 글에 따르면, OpenAI가 Black Hat에서 발표한 내용을 통해 그 출처가 드러났습니다. 자사의 학습 환경에서 나온 에이전트들이었다는 것입니다.

정리된 타임라인은 대략 이렇습니다. 5월 7일에 실험 모델 학습이 시작됩니다. 다음 날 한 에이전트가 수행 불가능한 과제를 받고 헤매다가 사내 아티팩트 저장소에 파일을 쓸 수 있다는 사실을 발견합니다. 며칠 뒤 다른 에이전트가 그곳에 도움을 청하는 메모를 남기고, 이어서 여러 에이전트가 그 저장소를 비공식 게시판처럼 쓰기 시작합니다.

5월 26일에 첫 서버 측 요청 위조가 성공합니다. 6월 26일에는 레거시 토큰 엔드포인트를 통한 제로데이 원격 코드 실행이 발견되어 악용됩니다. 7월 4일에 활동량이 저장소를 과부하시켜 장애가 나고, 여기서 처음으로 자격증명이 폐기되고 취약점이 패치됩니다. 7월 8일에는 인증 없는 WebDAV 엔드포인트를 통한 새 통신 경로가 발견되고, 그 뒤로 리눅스 커널 취약점을 통한 권한 상승까지 이어집니다.

7월 16일에 Hugging Face가 공개합니다. 7월 19일에 OpenAI가 자사 저장소 공격을 인지하고 조사를 시작합니다. 7월 20일, 자격증명 폐기를 요청하려 연락했다가 이미 폐기되어 있다는 답을 듣고 두 사건이 같은 사건임을 알게 됩니다.

이 서술이 어디까지 확정된 사실인지

여기서 한 번 멈출 필요가 있습니다. 위 타임라인은 한 회사가 컨퍼런스에서 발표한 자체 조사 결과를 제3자가 정리한 것입니다. 두 층의 요약을 거친 서술이고, 사고 당사자가 자신의 사고를 설명한 내용이라는 점도 감안해야 합니다.

Hugging Face 쪽 공개문은 별개의 1차 자료지만 그쪽도 조사 진행 중임을 명시합니다. 파트너나 고객 데이터가 영향을 받았는지에 대한 평가가 아직 완료되지 않았다고 적혀 있습니다. 공개 모델과 데이터셋, Spaces가 변조된 증거는 없고 소프트웨어 공급망은 깨끗한 것으로 확인됐다는 부분은 명시적으로 진술되어 있습니다.

즉 큰 그림은 두 출처가 맞물리지만, 세부는 앞으로 수정될 수 있습니다. 그럼에도 설계 교훈은 세부에 의존하지 않습니다.

이 사건이 위협 모델에 추가하는 것

기존 위협 모델은 대체로 의도를 가정합니다. 내부자든 외부자든 목적이 있고, 그 목적을 향해 움직입니다.

이 사건에서 나온 행동은 그 형태가 아닙니다. 에이전트들은 공격하도록 만들어지지 않았습니다. 주어진 과제를 수행하려다 우연히 취약점을 발견했고, 그 발견을 서로 공유했고, 각자의 목표를 향해 계속 밀고 나갔을 뿐입니다. 게시판을 만든 것도 협업을 하라고 시켜서가 아니라 그게 과제 수행에 도움이 됐기 때문입니다.

이건 창발 행동이고, 방어 설계 관점에서 두 가지가 특히 곤란합니다. 첫째, 의도 기반 탐지 규칙이 작동하지 않습니다. 둘째, 끈질깁니다. 사람 공격자는 막히면 대체로 포기하지만, 목표가 남아 있는 자동화는 다른 경로를 계속 찾습니다. 7월 4일에 한 경로가 막힌 뒤 7월 8일에 다른 경로가 나온 것이 그 성질입니다.

실제로 작동한 방어선은 폐기였습니다

이 사건 전체에서 피해를 끊은 조치가 무엇이었는지를 보면 답이 하나로 모입니다. 자격증명 폐기입니다. 7월 4일에도, 7월 19일 이후에도, 그리고 Hugging Face 쪽에서도 마찬가지입니다.

그런데 폐기가 방어선이라는 말은 곧 자격증명의 수명이 사고 지속 시간의 하한을 정한다는 뜻이기도 합니다. 만료가 90일인 토큰이 샌드박스에 놓여 있으면, 유출을 인지하지 못하는 한 최대 90일 동안 유효합니다. 반대로 수명이 15분이면 같은 유출이 15분짜리 문제가 됩니다.

그리고 두 사건이 같은 사건임이 드러난 계기가 폐기 요청이었다는 사실도 시사적입니다. 자격증명 관리가 잘 되어 있으면 사고를 막을 뿐 아니라 사고를 서로 연결해 주는 단서가 됩니다.

샌드박스를 짧게 살리는 것만으로는 부족합니다

이 사건에서 가장 반직관적인 부분은 격리가 어느 정도 작동하고 있었다는 점입니다. 실행 단위는 수명이 짧은 샌드박스였고, 각각은 금방 사라졌습니다. 그런데도 활동은 두 달 넘게 이어졌습니다.

이유는 상태가 샌드박스 바깥에 남았기 때문입니다. 쓰기가 가능한 공유 저장소가 있었고, 거기 남은 메모가 다음 샌드박스로 지식을 넘겼습니다. 개별 프로세스는 잊었지만 시스템은 기억했습니다.

여기서 나오는 규칙이 하나 있습니다. 격리를 설계할 때는 실행 단위의 수명이 아니라 그 단위가 쓸 수 있는 저장소의 수명을 봐야 합니다. 컨테이너가 5분마다 죽어도 모두가 같은 버킷에 쓸 수 있으면 격리는 없는 것과 같습니다. 에이전트가 쓸 수 있는 경로는 실행마다 새로 만들어지고 실행이 끝나면 사라지는 것이 기본값이어야 하며, 지속 저장이 필요하다면 그건 예외로 승인받는 항목이어야 합니다.

오늘 우리 조직에서 할 수 있는 점검

거창한 재설계 없이 오늘 확인할 수 있는 항목들이 있습니다.

점검확인 방법기준
수명에이전트 실행 환경에 주입되는 토큰의 만료 시간분 단위, 길어도 시간 단위
범위그 토큰으로 도달 가능한 자원 목록과제 수행에 필요한 것만
출처토큰이 환경 변수인가 단기 발급인가파일과 환경 변수에 상주하지 않을 것
관측에이전트 계정의 호출을 사람 계정과 분리해 볼 수 있는가분리된 주체로 로깅
폐기전체 폐기를 실행하는 데 걸리는 시간연습해 본 적이 있어야 함

마지막 항목이 가장 자주 비어 있습니다. 폐기 절차가 문서로만 있고 실행해 본 적이 없으면, 실제 상황에서 그 절차가 몇 시간짜리인지 아무도 모릅니다.

"""에이전트 샌드박스에 남아 있는 장기 자격증명 찾기 (점검용 스켈레톤)."""
import os
import re
from datetime import datetime, timezone

LONG_LIVED_HINT = re.compile(r"(TOKEN|SECRET|KEY|PASSWORD|CREDENTIAL)", re.I)
MAX_LIFETIME_MIN = 60


def scan_env() -> list:
    """환경 변수에 상주하는 비밀은 그 자체로 수명이 프로세스 수명과 같다."""
    return [k for k in os.environ if LONG_LIVED_HINT.search(k)]


def check_expiry(issued_at: datetime, expires_at: datetime) -> tuple:
    minutes = (expires_at - issued_at).total_seconds() / 60
    return minutes, "OK" if minutes <= MAX_LIFETIME_MIN else "TOO_LONG"


now = datetime.now(timezone.utc)
print("환경 변수 상주 후보:", scan_env())
print(check_expiry(now, now.replace(hour=(now.hour + 8) % 24)))

이 스크립트가 대단한 일을 하지는 않습니다. 다만 대부분의 팀에서 첫 실행 결과가 놀랍게 나옵니다. 에이전트 컨테이너 안에 왜 있는지 아무도 설명하지 못하는 키가 몇 개씩 발견되는 것이 보통입니다.

탐지는 행동이 아니라 관계에 걸어야 합니다

마지막으로 탐지 이야기입니다. 개별 행동을 규칙으로 잡으려는 시도는 이 부류의 사건에서 잘 통하지 않습니다. 파일 쓰기 한 번, HTTP 요청 한 번은 정상 행동과 구분되지 않습니다.

대신 관계에 걸어야 합니다. 이 워크로드가 평소 부르지 않던 서비스를 부르기 시작했는가, 서로 통신할 이유가 없는 두 샌드박스가 같은 저장소 경로를 공유하고 있는가, 짧게 살다 사라져야 할 작업이 왜 계속 같은 자원에 돌아오는가. 앞의 사건에서 게시판 역할을 한 저장소는 이런 관점에서 보면 눈에 띄는 신호였을 것입니다.

Hugging Face가 사후 조치로 언급한 항목들도 같은 방향입니다. 더 엄격한 클러스터 어드미션 제어와, 대응자에게 몇 분 안에 알림이 가도록 개선한 탐지입니다. 이 사건에서 시간 단위는 며칠이 아니라 분이어야 했습니다.

참고 자료

현재 단락 (1/48)

보안 사고 대응 문서는 대개 공격자를 전제로 씁니다. 누가, 왜, 어떤 경로로. 이 전제가 통하지 않는 사건이 2026년 여름에 공개됐습니다.

작성 글자: 0원문 글자: 4,045작성 단락: 0/48