AI보안 3분 소요

AI 모델 저장소가 뚫렸다면? 우리가 무심코 내려받는 오픈 모델의 불편한 진실

우리는 이제 모델을 git clone 하듯 내려받습니다. Hugging Face에서 가중치 파일 몇 GB를 받아 서버에 올리고, 별다른 의심 없이 실행합니다. 그런데 그 파일 안에 무엇이 들어 있는지 직접 확인해 본 적 있으신가요. 소프트웨어 공급망 보안은 지난 몇 년간 업계의 화두였는데요, 유독 AI 모델만은 이 논의에서 조용히 빠져 있었습니다.

먼저 솔직하게 말씀드리자면, 이 주제로 최근 30일간의 커뮤니티 논의를 살펴봤지만 유의미한 신규 스레드는 잡히지 않았습니다. 그래서 이 글은 실시간 반응 정리라기보다, 이미 알려진 구조적 취약점을 정리하고 왜 이게 여전히 위험한지 짚는 쪽에 가깝습니다.

모델 파일은 데이터가 아니라 코드일 수 있습니다

가장 근본적인 문제부터 짚겠습니다. 많은 분들이 모델 가중치를 단순한 숫자 덩어리로 생각합니다. 이미지 파일이나 CSV처럼 그냥 데이터라고요.

그런데 PyTorch의 전통적인 .bin, .pt, .pth 파일은 파이썬의 pickle 포맷을 씁니다. pickle은 객체를 저장할 때 복원 방법을 코드로 기술하는 구조입니다. 즉, 역직렬화하는 순간 임의의 파이썬 코드가 실행될 수 있습니다.

torch.load() 한 줄이 사실상 낯선 사람이 보낸 스크립트를 실행하는 것과 같다는 뜻입니다. 공식 문서에도 신뢰할 수 없는 소스의 파일을 로드하지 말라는 경고가 명시돼 있습니다. 하지만 현실에서 그 경고를 읽고 멈추는 사람이 몇이나 될까요.

Hugging Face가 safetensors 포맷을 밀고 있는 이유가 정확히 여기에 있습니다. safetensors는 텐서 데이터만 담고 실행 가능한 코드를 담지 못하도록 설계됐습니다. 다만 문제는, 아직도 상당수의 저장소가 레거시 pickle 파일을 함께 제공하고 있다는 점입니다.

진짜 위험한 건 가중치가 아니라 trust_remote_code

가중치보다 더 넓게 열린 문이 있습니다. Transformers 라이브러리의 trust_remote_code=True 옵션입니다.

새로운 아키텍처의 모델을 쓰려면 이 옵션이 필요한 경우가 많습니다. 그러면 라이브러리가 모델 저장소에 들어 있는 파이썬 파일을 그대로 임포트해서 실행합니다. 가중치를 뜯어볼 필요조차 없습니다. 저장소에 .py 파일 하나만 심으면 됩니다.

더 씁쓸한 건 이 옵션이 사실상 관행이 됐다는 점입니다. 최신 모델을 돌리려다 에러가 나면 스택오버플로우나 이슈 트래커에서 “trust_remote_code=True 붙이세요"라는 답을 만납니다. 그리고 대부분 붙입니다. 돌아가니까요. 보안 경고가 일상적인 트러블슈팅 단계로 흡수되는 순간, 그 경고는 이미 기능을 잃은 겁니다.

검증되지 않은 신뢰가 쌓이는 구조

공급망 공격의 고전적인 시나리오를 모델 생태계에 대입해 보겠습니다.

첫째, 타이포스쿼팅입니다. 유명 모델 이름과 한 글자 다른 저장소를 만들어 둡니다. npm과 PyPI에서 수없이 반복된 수법인데, 모델 허브라고 다를 이유가 없습니다.

둘째, 계정 탈취입니다. 신뢰받는 조직 계정이 뚫리면, 이미 수만 명이 참조 중인 저장소의 파일이 조용히 교체될 수 있습니다.

셋째, 파인튜닝 체인 오염입니다. 오픈 모델 생태계는 베이스 모델을 누군가 파인튜닝하고, 그걸 또 누군가 병합하고, 다시 양자화하는 식으로 이어집니다. 이 체인의 중간 어딘가만 오염돼도 하위 파생 모델 전체가 영향을 받습니다. 그리고 대부분의 사용자는 자기가 쓰는 모델의 계보를 3단계 이상 거슬러 확인하지 않습니다.

평가와 벤치마크 파이프라인이라는 사각지대

특히 위험한 지점이 모델 평가 파이프라인입니다.

평가는 성격상 신뢰도가 낮은 모델을 잔뜩 끌어와 실행하는 작업입니다. 리더보드를 돌리든, 사내에서 후보 모델을 비교하든 마찬가지입니다. 그런데 이런 평가 환경은 아이러니하게도 권한이 넉넉한 GPU 서버에서 돌아갑니다. 클라우드 자격 증명이 붙어 있고, 내부 데이터셋에 접근하고, 결과를 사내 저장소에 씁니다.

공격자 입장에서 이보다 매력적인 표적이 없습니다. 임의의 코드를 실행할 수 있는 파일을, 상대가 알아서 고성능 서버에 내려받아 실행해 주니까요. 게다가 그 서버는 대개 격리돼 있지 않습니다. “그냥 모델 평가하는 장비"라는 인식 때문에 보안 검토 대상에서 빠지기 쉽습니다.

그래서 무엇을 해야 하나

거창한 대책이 필요한 게 아닙니다. 몇 가지 습관이면 위험의 상당 부분이 줄어듭니다.

safetensors만 받기가 첫걸음입니다. 저장소에 safetensors 버전이 있으면 그것만 명시적으로 지정해 받으세요. pickle 파일밖에 없다면 그 자체가 신호입니다.

리비전 고정도 중요합니다. 모델을 태그나 브랜치 이름이 아니라 커밋 해시로 고정하세요. 저장소가 나중에 오염돼도 내가 검증한 시점의 파일을 계속 씁니다. 코드에서 revision 인자에 해시를 박아 두는 것만으로 됩니다.

trust_remote_code는 예외 처리로 다루세요. 기본값처럼 붙이지 말고, 붙여야 한다면 해당 저장소의 파이썬 파일을 실제로 열어 읽고, 그 실행을 격리된 컨테이너로 제한하는 게 맞습니다.

마지막으로 평가 환경 격리입니다. 검증되지 않은 모델을 돌리는 장비에 프로덕션 자격 증명을 두지 마세요. 네트워크 아웃바운드를 막고, 일회용 컨테이너에서 돌리고, 끝나면 버리는 구조가 이상적입니다.

마무리

우리는 npm 패키지 하나를 설치할 때는 다운로드 수와 최근 커밋을 확인하면서, 수 GB짜리 모델은 이름만 보고 받습니다. AI 도입 속도가 보안 습관의 형성 속도를 한참 앞질러 버린 결과인데요.

지금 여러분의 파이프라인에서 돌아가는 모델은 어디서 왔고, 누가 만들었으며, 마지막으로 파일이 바뀐 게 언제인지 답할 수 있으신가요. 그 질문에 바로 답하지 못한다면, 그게 바로 사각지대입니다.

AI보안 공급망보안 HuggingFace 오픈소스 MLOps

댓글

    댓글을 불러오는 중...