토스의 LLM + SAST + Multi-Agent 기반 취약점 분석 자동화 사례 공유
토스 보안팀이 코드 인덱싱 MCP + SAST 기반 입력 경로 추출 + Discovery/Analysis 분리 + Qwen3:30B 전환으로 50% 경로 최적화 + 100% 정탐률 달성
요약
토스 Security Researcher가 LLM 취약점 분석 자동화 후속 — 4개 벽(대용량 코드 전달·분석 일관성·비용 효율·지속 가능성)을 단계별로 해결. ctags+tree-sitter MCP 서버로 코드 탐색 정확도 확보, Semgrep SAST를 "취약점 탐지"가 아니라 "AI가 검토할 입력 경로 추출" 보조로 사용, Discovery→Analysis Multi-Agent로 Cloud Model 비용 문제는 Open Model(Qwen3:30B) + Pydantic/Instructor 보정으로 해결.
내용
지난 글(2025-12-25)에서 다룬 LLM 취약점 분석 자동화 구현 디테일을 다루는 후속편. 3개월 사이 AI 취약점 분석 능력이 크게 올라온 시점에서, 토스 보안팀이 부딪힌 4개 벽과 그 해법을 코드·툴·아키텍처 수준에서 풀이.
XBOW 프로젝트(인간 개입 없이 AI 에이전트로 취약점 발견, HackerOne USA 1위·CVE 다수)를 참고. 작성자 입장은 자체 분석 기술 개발보다 어떤 모델·에이전트가 들어와도 붙일 수 있는 인프라(소스코드 인덱싱 서버 + MCP 표준)에 집중하는 방향.
해결 / 접근
1. 대용량 코드 효율 전달 — SourceCode-Browse MCP
- Cursor·Claude Code는 단순 패턴 매칭(Ripgrep)만 사용, 사전 인덱싱 없음 → 토큰 낭비
- ctags로 심볼 정의 사전 인덱싱 + tree-sitter로 함수 범위 구조적 파싱
- "이 함수의 정의를 보여줘" 요청 시 grep 대신 인덱스에서 즉시 정확한 위치 반환 → IDE의 Go to Definition / Find References 수준
- 도구 4개:
- find_references() — ripgrep 기반 심볼/패턴 검색
- read_definition() — ctags 인덱스 + tree-sitter 함수 범위 감지
- read_source() — 특정 라인 주변 소스코드 읽기
- get_project_structure() — 디렉터리 구조 반환 (원격 환경에서 청사진 역할)
- 원격 자동화 목표라 로컬 IDE 의존 X
2. 일관성 없는 결과 — SAST를 입력 경로 추출용으로 전용
- 기존 SAST 사용법은 "SAST 결과를 AI에 전달" → AI 커버리지가 SAST 도구만큼으로 한정 (SAST 리뷰어 수준)
- 가설: AI가 취약점을 누락하는 이유는 이해력이 아니라 "취약 코드를 못 봤기" 때문. 패턴 자체는 단순함
- Semgrep으로 모든 Untrusted Input → Sink 도달 경로 추출 (Source/Sink 룰)
- 결과 포맷: SARIF (국제 표준 JSON)
- "취약점 찾기"가 아니라 "AI가 반드시 검토할 후보군 전수 추출"
SAST 결과 다이어트
- 큰 프로젝트는 SARIF가 MB 단위(15MB까지 봄), 그대로 전달하면 컨텍스트 대부분 낭비
- 필요 정보(파일 경로·정확한 위치·코드 스니펫)만 JSONL로 변환
- 연속 라인(38, 39, 40)이 ID별로 분리되어 토큰 낭비 → 연속 라인 merge 후처리
3. 비효율적 분석 — Multi-Agent (Discovery → Analysis)
- 100개 경로 중 의미 있는 건 10개여도 90개를 다 분석하면 비용 과다
- XBOW의 Discovery Agents → Attack Agents 구조 차용
- Supervisor: Discovery·Analysis에 지시
- Discovery: 모든 경로 중 취약점 가능성 높은 경로만 선별 (필터)
- Analysis: 선별된 경로에 대해서만 실제 분석
- Discovery·Analysis만 SourceCode-Browse MCP 사용
Discovery 트레이드오프
- Discovery가 소스코드 깊이 참조하면 Analysis와 토큰 2배 부담 → 에이전트 분리 의미 옅어짐
- System Prompt 설계: 미탐률보다 과탐률이 높은 게 낫다는 판단으로 선별 기준 완화
- 의미 없는 경로가 일부 포함되어도 기존 대비 현저히 감소
4. 지속 가능성 — Cloud Model → Open Model 전환
- 토스 수백 개 서비스를 매일 분석하면 한 달 수백만 원
- 후보 3개: Qwen3:30B / gpt-oss:20B / llama3.1:8B
- 평가용 샘플 웹 프로젝트 제작 — XSS, IDOR, Deserialize, Path Traversal 포함
- 메모리·캐시 통제된 환경에서 분석률·정탐률·오탐률 측정
- MCP Tool Calling 안정성과 토큰 효율도 평가 — LangSmith로 멀티턴 대화·도구 호출·I/O 토큰 모니터링
- Qwen3:30B 채택
Open Model 응답 안정성 보완
- Open Model은 응답 포맷·가이드라인을 자주 어김
- Pydantic으로 응답 타입 힌트·검증 강화 → 포맷 미일치 시 에러
- Instructor로 에러 내용을 LLM에 다시 전달, 자동 보정
- 추가 안정화: task를 더 잘게 쪼개 여러 에이전트에 분산
결과 / 참고
- 286개 입력 경로 → Discovery가 144개 선별 → 27개 취약점 발견
- 50% 가까운 경로 최적화 + 100% 정탐률 (오탐 일부 포함)
- Cloud Model → Open Model 전환으로 지속 가능 비용 구조 확보
- 토스에는 Qwen3.5 122B A10B (GPT-4o급) 사용 가능 환경 존재
- 향후 방향: 소스코드 인덱싱 서버 — 모든 서비스 소스코드 중앙 서버에 인덱싱, AI 에이전트가 어디서든 최신 코드 참조, MCP 표준 위에서 Claude·Codex·미래 에이전트가 인프라 변경 없이 연결
- 출처: toss tech (LLM 취약점 분석 자동화 #2, 2026)
- 작성자: 토스 Security Researcher 표상영
- 참고: XBOW 프로젝트, Anthropic Claude Code subAgent (2026-02-05), OpenAI Codex-Security (2026-03-06)
- 사용 도구: ctags, tree-sitter, ripgrep, Semgrep, SARIF, JSONL, Pydantic, Instructor, LangSmith, LangGraph