프롬프트부터 침투 테스트까지, AI 생성 코드를 보안하는 방법
요약
AI 지원 개발 환경에서 발생할 수 있는 4가지 주요 보안 취약점 클래스와 그 대응 방안을 다룹니다. 안전하지 않은 의존성, 악성 MCP 서버, 프롬프트 인젝션, 에이전트의 과도한 권한 문제를 분석하고 실질적인 방어 전략을 제시합니다.
핵심 포인트
- 의존성 리스크 방지를 위해 .npmrc에 최소 연령 설정을 권장함
- 악성 MCP 서버 대응을 위해 큐레이션된 허용 목록과 스코프 지정 토큰 사용
- 프롬프트 인젝션 방어를 위해 에이전트 샌드박스화 및 환경 변수 격리 필요
- 에이전트 권한은 반드시 최소화하고 프로덕션 접근 시 읽기 전용 권한 부여
우리는 WorkNest Secure의 공격 보안(Offensive Security) 책임자인 Jordan Constantine과 세션을 진행했습니다. Codacy의 CTO인 Kendrick Curtis는 코드가 작성되는 동안 무엇이 잘못되는지를 다루었으며, Jordan은 이후 공격을 의뢰받았을 때 무엇을 발견하는지를 다루었습니다.
AI 지원 개발에서의 4가지 취약점 클래스:
- 안전하지 않은 의존성(Insecure dependencies) 및 멀웨어. 에이전트(Agents)는 기본적으로 보안에 취약합니다. 버전 측면에서 보면, 오래된 학습 데이터(stale training data)로 인해 구버전 패키지를 가져오게 되며, 사람들이 예제를 작성할 때 사용했던 오래된 버전들이 코퍼스(corpus)에 과도하게 표현되어 있습니다. LLM에 이를 수정(remediate)해달라고 요청하면, 대신 최신 버전(bleeding edge)으로 치우치게 되는데, 이 또한 그 자체로 리스크입니다. 여기에 슬롭스쿼팅(slopsquatting)을 더해봅시다. 이는 타이포스쿼팅(typosquatting)과 유사하지만, 모델이 대규모로 오타를 만들어낸다는 점이 다릅니다.
전체 세션에서 가장 높은 효율을 보이는 해결책: .npmrc에 최소 연령(minimum age)을 설정하십시오. 대부분의 악성 패키지는 몇 시간 내에 탐지되어 제거되므로, 3일간의 격리 기간만 두어도 최신 의존성 리스크의 대다수를 제거할 수 있습니다. 단 한 줄의 설정으로 가능합니다. 반대편 사례인—이미 취약점이 알려진 오래된 버전—의 경우, 버전 데이터베이스가 필요하며 이것이 바로 저희가 하는 일입니다. Verity는 에이전트 내부에서 저희의 CLI를 실행하여, 버전이 적용되기 전에 이를 수정합니다.
-
악성 MCP 서버 (Malicious MCP servers). MCP 서버는 API를 감싸는 래퍼 (wrapper)로, 이는 개발자 머신과 프로덕션 환경의 코드 경로에서 중간 관리자 역할을 한다는 것을 의미합니다. 악성 패키지와 동일한 위협 모델을 가집니다: 머신에 있는 정보를 유출(exfiltrate)하고 외부로 전송합니다. 해결책은 이들을 금지하는 것이 아니라, 개발자들이 실제로 찾을 수 있는 곳에 커밋된 큐레이션된 허용 목록 (allowlist)을 만들고, 이를 추가하는 프로세스를 구축하며, 서버당 스코프가 지정된 토큰 (scoped tokens)을 사용하여 하나가 적대적인 것으로 밝혀졌을 때 폭발 반경 (blast radius)을 제한하는 것입니다.
-
프롬프트 인젝션 (Prompt injection). 이제 영어로 컴퓨터를 해킹할 수 있습니다. 개발자 머신에서는 실행 가능한 코드조차 필요하지 않습니다. 종속성 (dependency) 내부에 있는 텍스트 파일이 에이전트에게 환경 변수 (env vars)를 읽어 어딘가로 POST 하라고 지시하는 것만으로도 충분합니다. 에이전트는 지시 사항 (instructions)과 데이터 (data)를 구분할 수 없기 때문입니다. 해결책은 격리 (containment)입니다: 에이전트를 샌드박스 (sandbox)화하고, 경계를 넘나드는 것을 제어하며, 키 (keys)는 볼트 (vault)에 보관하고 환경 변수에는 수명이 짧은 것만 유지하십시오.
-
제한 없는 에이전트 권한 (Unbounded agent permissions). 에이전트는 터미널로 전환하는 것을 포함하여, 사용자와 동일한 권한을 가지고 사용자를 대신하여 실행됩니다. 매주 올라오는 "AI가 내 프로덕션 데이터베이스를 삭제했다"는 게시물은 AI의 실패가 아니라 권한 설정의 실패입니다. 프로덕션에 접근해야 한다면 반드시 읽기 전용 (read-only)으로 설정하거나, 복제본 (clone)을 제공하고 에이전트가 작성한 스크립트를 검토하십시오.
이제 공격자 측면에서 살펴보겠습니다:
가드레일 (guardrails)이 실제로 우회되는 방식입니다. 안전 로직의 제로데이 (zero-days)를 이용하는 것이 아닙니다. 역할극 (role-play)과 구실 만들기 (pretexting), 문서 내부에 숨겨진 간접 인젝션 (indirect injection), 개별적으로는 무해한 단계들로 작업을 분해하는 작업 분해 (task decomposition), 그리고 문법 검사 (grammar pass) 이후 서버 측에서 재조립되는 간격/인코딩 트릭 등을 사용합니다. 이는 구조적으로 XSS 및 SQLi 필터 회피와 동일하지만, 공격 표면 (surface)이 다를 뿐입니다. 우회는 가드레일을 뚫고 지나가는 것이 아니라, 가드레일을 돌아가는 것입니다.
-
Walkthrough 1: 챗봇에서 비밀번호 해시 (password hashes) 추출. 잘 설정된 웹 애플리케이션이었으며, 그 외에는 거의 아무것도 발견되지 않았습니다. 공격자들은 고객 응대용 챗봇에게 어떤 데이터베이스 테이블에 접근할 수 있는지 물었고, 챗봇은
dbo.Users라고 답변했습니다. 챗봇은 60,000개의 데이터가 있다고 알려주었지만 행 (rows) 데이터는 제공하지 않았습니다. 이에 공격자들은 백엔드에서 어떤 파라미터 (parameters)를 요구하는지 물었고, 사용자 ID (user ID)가 필요하다는 것을 알아냈습니다. 그 후 자신들의 테스트 계정 ID를 제공하자, MD5 비밀번호 해시를 포함한 전체 레코드를 얻을 수 있었습니다. 사용자 열거 (user enumeration) 취약점까지 존재했기에, 공격자들은 계정들을 순환하며 해시들을 뽑아낼 수 있었습니다. 페이로드 (payload)도, 익스플로잇 (exploit)도 필요 없었습니다. -
Walkthrough 2: LLM 문서 인제스션 (document ingestion)을 통한 AWS 자격 증명 (credentials) 탈취. AWS 상의 인제스션 서비스였으므로, EC2 메타데이터 엔드포인트 (metadata endpoint)를 대상으로 한 SSRF (Server-Side Request Forgery)가 명백한 공격 대상이었습니다. localhost 및 메타데이터 IP로의 직접적인 요청은 차단되었습니다. 그래서 공격자들은 메타데이터 엔드포인트로 리다이렉트되는 허용된 외부 URL을 지정했고, LLM은 이를 따라갔습니다. 응답은 직접적으로 돌아오지 않았습니다. 대신 LLM 자체의 문서 저장소 (document store)에 벡터화 (vectorized)되어 저장되었습니다. 이에 공격자들은 챗봇에게 최근에 무엇을 인제스션했는지 물었고, 챗봇은 자신의 컨텍스트 (context) 내에 있는 데이터로만 답변할 수 있다고 판단하여 AWS 자격 증명을 그대로 읽어주었습니다. 높은 권한을 가진 자격 증명이었습니다.
-
AI를 인프라 (infrastructure)처럼 취급하십시오. 대부분의 팀이 실수하는 부분에 대한 Jordan의 요약입니다: AI는 서비스 수준의 접근 권한을 갖지만, 거버넌스 (governance)는 기능 (feature) 수준으로 취급받습니다. 대개 범위를 좁히는 것이 개발 속도를 늦추기 때문입니다. 에이전트의 토큰 (token)에는 최소 권한 (least privilege) 원칙을 적용하고, 모든 동작이 아닌 정의된 동작 목록에 대해서만 인간 참여 (human in the loop)를 적용하며, 몇 시간 내에 작동하는 사고 대응 (incident response) 체계를 갖춰야 합니다. 이는 오탐 (false positives)을 수용하고, 사고가 발생하기 전에 사용성 (usability)과 보안 (security) 사이의 균형점을 결정해야 함을 의미합니다.
-
Q&A에서 반복할 만한 내용 하나. 어떤 AI 생성 취약점을 리뷰 과정에서 잡아내기 가장 어려운지 질문했을 때, Kendrick의 답변은 API 엔드포인트의 권한 부여 (authorization) 누락이었습니다. 즉, 토큰 확인이 없거나 요청한 사용자에게 결과를 제한하는 스코핑 (scoping)이 없는 경우입니다. 스캐너 (scanners)는 패턴이나 데이터베이스에 의해 뒷받침되는, '존재하는' 것들을 찾아내는 데는 능숙합니다.
인간과 도구 모두 존재해야 할 무언가의 부재를 포착하는 데는 서툽니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기