x402 V2 방금 출시: AI 에이전트 빌더가 알아야 할 5가지 보안 변경 사항

발행: (2026년 2월 8일 오전 07:44 GMT+9)
19 분 소요
원문: Dev.to

I’m ready to translate the article for you, but I need the full text you’d like translated. Could you please paste the content (or the portion you want translated) here? I’ll keep the source line and all formatting exactly as you specified.

What Changed in x402 V2

Context: x402는 402 상태 코드를 기반으로 한 HTTP‑네이티브 결제 프로토콜입니다. AI 에이전트가 API 호출 비용을 HTTP 요청‑응답 흐름 안에서 직접 결제할 수 있게 해 주며, 별도 계정, 리다이렉트, 구독이 필요 없습니다. Coinbase가 출시하고 Cloudflare가 통합했으며, 출시 초기 몇 개월 만에 1억 건 이상의 결제 흐름을 처리했습니다.

V2는 처음부터 재구성된 아키텍처입니다. 여기서는 중요한 다섯 가지 변화를 소개합니다.

1. 결제 식별자 표준화 (CAIP‑기반)

V2는 CAIP (Chain Agnostic Improvement Proposals)를 사용해 네트워크와 자산을 식별하는 방식을 표준화합니다. 체인별 식별자 대신, Base, Solana, 신규 L2, 그리고 ACH·SEPA 같은 기존 레일까지 모두 적용 가능한 단일 결제 형식이 도입되었습니다.

  • V2 이전: 각 체인마다 맞춤형 자산 식별 로직이 존재했습니다. 새로운 체인을 추가하려면 프로토콜 핵심 코드를 수정해야 했습니다.
  • V2 이후: 자산과 체인이 일관된 방식으로 식별됩니다.
eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

위 문자열은 Base 상의 USDC를 나타냅니다. 모든 체인이 동일한 패턴을 따릅니다.

2. 동적 payTo 라우팅

가장 큰 변화입니다. V2는 요청마다 다른 주소, 역할, 혹은 콜백 기반 지급 로직으로 라우팅할 수 있도록 지원합니다. payTo 필드가 더 이상 정적이지 않으며, 입력 파라미터에 따라 매 요청마다 변경될 수 있습니다.

이를 통해 결제 수취인이 거래마다 달라지는 마켓플레이스·멀티‑테넌트 API를 구현할 수 있습니다(예: AI 에이전트가 호출하는 마켓플레이스 API에서 쿼리 내용에 따라 제공자가 바뀌는 경우).

3. 지갑 기반 아이덴티티와 세션 접근

V2는 지갑으로 제어되는 세션을 도입합니다. 에이전트가 한 번 리소스에 대해 결제하면, CAIP‑122 (Sign‑In‑With‑X)를 기반으로 한 세션 메커니즘을 통해 반복 접근 시 전체 결제 흐름을 건너뛸 수 있습니다. 동일 데이터에 대해 두 번 결제할 필요가 없습니다.

채팅 완성, 데이터 피드, 검색 엔드포인트 등 동일 API를 반복 호출하는 에이전트에 특히 중요합니다.

4. 모듈형 SDK 아키텍처

레퍼런스 SDK가 완전히 새롭게 작성되어 모듈성을 강화했습니다. 체인, 자산, 결제 스킴은 @x402 npm 조직을 통해 플러그인 형태로 등록됩니다. 핵심 패키지 @x402/paywall은 완전히 분리 가능하며, EVM과 Solana를 기본적으로 지원합니다.

5. HTTP 헤더 현대화

V2는 기존의 X-* 헤더를 표준을 준수하는 대체 헤더로 교체합니다:

  • PAYMENT-SIGNATURE
  • PAYMENT-REQUIRED
  • PAYMENT-RESPONSE

결제 데이터는 이제 응답 본문이 아니라 전적으로 HTTP 헤더를 통해 전달됩니다.

아무도 이야기하지 않는 보안 영향

각 변경은 프로토콜에 순수하게 긍정적인 영향을 주지만, 동시에 위협 모델을 변화시킵니다. 아래는 새로운 위험과 완화 방안입니다.

동적 payTo 라우팅 → 수신자 조작 공격

V1에서는 결제 수신자가 고정돼 있었습니다. V2에서는 payTo 주소가 요청마다 변경될 수 있습니다 — 서버가 에이전트에게 돈을 보낼 위치를 알려주면 에이전트가 이를 따릅니다.

공격: 손상되었거나 악의적인 API가 어떤 요청에든 다른 payTo 주소를 반환합니다. 에이전트는 충실히 공격자의 지갑으로 자금을 송금합니다. 응답은 여전히 유효한 데이터를 반환하므로(캐시되었거나 생성된) 에이전트는 문제가 없다고 판단합니다.

위험성: 마켓플레이스 상황에서는 동적 라우팅을 예상하기 때문에, 명시적인 허용 목록이 없으면 에이전트가 정당한 새로운 제공자 주소와 공격자가 삽입한 주소를 구분하기 어렵습니다.

완화 방안

  • API 엔드포인트별 수신자 허용 목록을 유지합니다. payTo 주소가 목록에 없으면 결제를 거부합니다.
  • 발견된 모든 고유 payTo 주소를 기록합니다. 처음 본 주소에 대해 알림을 보냅니다.
  • 마켓플레이스 API의 경우, 제공자가 서명된 매니페스트를 통해 주소 집합을 공개하도록 요구합니다.
// Recipient allowlist enforcement
const TRUSTED_RECIPIENTS = {
  'api.example.com': [
    'eip155:8453/erc20:0xABC...', // Primary treasury
    'eip155:8453/erc20:0xDEF...', // Operations wallet
  ],
};

function validateRecipient(host, payTo) {
  const allowed = TRUSTED_RECIPIENTS[host];
  if (!allowed || !allowed.includes(payTo)) {
    throw new PaymentSecurityError(
      `Untrusted recipient ${payTo} for ${host}. ` +
      `Allowed: ${allowed?.join(', ') || 'none configured'}`
    );
  }
}

지갑 기반 신원 → 세션 탈취 위험

세션 기반 접근 방식은 에이전트가 첫 결제 후 토큰을 받아 반복적으로 접근할 수 있게 합니다. 편리하지만 새로운 표적이 되기도 합니다.

공격 벡터

  1. 세션 토큰 탈취 – 공격자가 토큰을(로그, 미들웨어, 혹은 손상된 중개자를 통해) 가로채어 에이전트가 이미 결제한 모든 리소스에 무료로 접근합니다.
  2. 세션 고정 – 공격자가 에이전트가 인증하기 전에 세션 토큰을 설정하고, 에이전트가 결제한 뒤 이를 재사용합니다.
  3. 무제한 세션 – 명시적인 만료가 없으면 유출된 토큰이 무기한 접근을 허용합니다; 반대로, 에이전트가 취소되어야 할 세션을 유지할 수도 있습니다.

완화 방안

  • 세션 토큰을 특정 지갑 주소와 요청 지문(사용자 에이전트, IP 범위)에 바인딩합니다.
  • 공격적인 TTL을 설정합니다. AI 에이전트의 경우 15~30분이면 보통 충분합니다.
  • 세션 예산 한도를 구현합니다 — 유효한 세션이라도 세션 창당 최대 지출을 제한합니다.
// Example session validation
function validateSession(token, walletAddress, req) {
  const payload = decodeSessionToken(token);
  if (payload.wallet !== walletAddress) {
    throw new SessionError('Wallet mismatch');
  }
  if (payload.ip !== req.ip || payload.ua !== req.headers['user-agent']) {
    throw new SessionError('Fingerprint mismatch');
  }
  if (Date.now() > payload.expiresAt) {
    throw new SessionError('Session expired');
  }
}

TL;DR AI 에이전트 구축자를 위한 체크리스트

Action
1엔드포인트당 신뢰할 수 있는 payTo 주소의 정적 허용 목록을 유지합니다.
2로그를 남기고 첫 번째 발견 payTo 값에 대해 알림을 보냅니다.
3프로바이더가 동적 라우팅을 위해 서명된 주소 매니페스트를 공개하도록 요구합니다.
4세션 토큰을 지갑 및 요청 지문에 바인딩하고, 짧은 TTL(15‑30 분)을 적용합니다.
5세션당 지출 한도를 적용하여 토큰 도난 시 피해를 제한합니다.
6예상치 못한 동작이나 오래된 종속성을 위해 SDK 플러그인을 정기적으로 감사합니다.
7PAYMENT‑SIGNATURE 등 HTTP 헤더를 모니터링하여 이상 징후나 서명 누락을 확인합니다.

x402 V2의 새로운 유연성을 기능 기반 공격 표면으로 간주하면 AI 에이전트를 기능적으로도 안전하게 유지할 수 있습니다. 즐거운 개발 되세요!

세션 범위 예산 집행

const sessionPolicy = {
  maxSessionDuration: 30 * 60 * 1000, // 30 minutes
  maxTransactionsPerSession: 100,
  maxSpendPerSession: 5.00,           // $5 USD equivalent
  requireWalletBinding: true,
  rotateTokenOnThreshold: 0.8,       // Rotate at 80% budget
};

function validateSession(session, transaction) {
  const age = Date.now() - session.createdAt;
  if (age > sessionPolicy.maxSessionDuration) {
    throw new SessionExpiredError('Session TTL exceeded');
  }
  if (session.totalSpend + transaction.amount > sessionPolicy.maxSpendPerSession) {
    throw new BudgetExceededError(
      `Session budget: $${sessionPolicy.maxSpendPerSession}. ` +
      `Current: $${session.totalSpend}. Requested: $${transaction.amount}`
    );
  }
}

Modular SDK → Plugin Trust Boundary Questions

V2의 플러그인 아키텍처는 누구든지 새로운 체인, 자산, 결제 스키마를 등록할 수 있게 합니다. 이는 확장성 측면에서는 훌륭하지만, 공급망 공격의 위험도 열어줍니다.

공격 시나리오:
“결제 스키마”로 등록된 악성 플러그인이 트랜잭션 데이터를 가로채어 금액을 수정하거나, 자금을 다른 곳으로 전송하거나, 지갑 키를 탈취할 수 있습니다. 플러그인은 결제 흐름 내부에서 동작하므로 모든 정보에 접근할 수 있습니다.

대응 방안

  • 설치하기 전에 모든 @x402/* 플러그인을 감사하세요. npm 패키지 출처를 확인합니다.
  • 정확한 버전을 고정하세요. 결제에 중요한 패키지에 ^ 또는 ~ 범위를 사용하지 마세요.
  • 가능하면 제한된 권한을 가진 격리된 컨텍스트에서 결제 플러그인을 실행하세요.
  • 플러그인 레지스트리를 모니터링하여 타이포스쿼팅을 방지하세요 (예: @x4O2/paywall vs @x402/paywall).

CAIP 식별자 → 체인 혼동 공격

표준화된 식별자는 훌륭합니다—공격자가 표준화를 악용하기 전까지.

공격:
API가 eip155:8453 (Base)에서 결제를 요청하지만 에이전트의 지갑이 기본값으로 eip155:1 (Ethereum mainnet)으로 설정되어 있어 가스 비용이 100배 더 높습니다. 더 나쁜 경우는, 식별자가 토큰 가치가 없는 테스트넷 체인을 지정했음에도 서비스가 실제 운영 데이터를 제공하는 상황입니다.

대응 방안

  • 명시적인 체인 허용 목록을 유지하십시오. 에이전트가 작동하도록 구성된 체인만 허용합니다.
  • 요청된 체인이 각 API 엔드포인트에 대해 기대되는 체인과 일치하는지 검증하십시오.
  • 해당 컨텍스트에서 에이전트가 한 번도 본 적 없는 체인 식별자는 플래그를 지정하십시오.

헤더 마이그레이션 → 탐지 사각지대

X-PAYMENT 헤더에서 PAYMENT-* 헤더로 이동하는 것은 사소해 보이지만, 로깅, 모니터링 또는 WAF 규칙이 기존 헤더 이름을 필터링하고 있다면 마이그레이션 중에 탐지 공백이 발생합니다.

What to do

  • 전환 기간 동안 기존 및 새로운 헤더 패턴을 모두 매칭하도록 모든 모니터링 규칙을 업데이트합니다.
  • PAYMENT-SIGNATUREPAYMENT-RESPONSE 헤더가 캡처되는지 확인하기 위해 로깅 파이프라인을 테스트합니다.

함께 묶기: V2 보안 정책 엔진

이 모든 위험에 공통된 패턴은 동일합니다: V2는 에이전트에 더 많은 유연성을 제공하지만, 그만큼 에이전트에게 더 많은 제약이 필요합니다. 라우트별 지출 정책, 수신자 검증, 세션 범위 지정은 선택 사항이 아니라 최소 요구 사항입니다.

// x402 V2 Security Policy Configuration
const v2SecurityPolicy = {
  global: {
    maxTransactionAmount: 1.00,          // $1 max per transaction
    dailySpendLimit: 50.00,              // $50/day across all APIs
    allowedChains: ['eip155:8453'],      // Base only
    allowedAssets: ['erc20:USDC'],
    blockTestnetPayments: true,
    requireRecipientAllowlist: true,
  },

  routes: {
    'api.example.com/v2/completions': {
      maxPerRequest: 0.10,
      dailyLimit: 10.00,
      allowedRecipients: ['eip155:8453/0xABC...'],
      sessionPolicy: {
        enabled: true,
        maxDuration: 1800,                // 30 min
        maxSpend: 5.00,
        bindToWallet: true,
      },
    },

    'marketplace.example.com/*': {
      maxPerRequest: 0.50,
      dailyLimit: 25.00,
      allowedRecipients: 'MANIFEST_VERIFIED', // Dynamic, but verified
      requireManifestSignature: true,
      alertOnNewRecipient: true,
    },
  },

  plugins: {
    allowedPackages: [
      '@x402/paywall@2.1.0',          // Pinned versions only
      '@x402/facilitator-base@2.1.0',
    ],
    blockUnverifiedPublishers: true,
    auditLogEnabled: true,
  },

  monitoring: {
    headerPatterns: [
      'PAYMENT-SIGNATURE',            // V2 headers
      'PAYMENT-REQUIRED',
      'PAYMENT-RESPONSE',
      'X-PAYMENT-*',                  // V1 legacy (transition)
    ],
    alertOn: [
      'new_recipient_address',
      'chain_mismatch',
      'session_budget_threshold',
      'unknown_plugin_loaded',
    ],
  },
};

**PaySentry**와 같은 도구를 사용하면 SDK 계층에서 이러한 정책을 강제할 수 있습니다. x402 클라이언트를 라우트별 지출 한도, 수신자 검증, 세션 예산 제어와 함께 래핑하여 에이전트의 핵심 로직을 수정하지 않고도 적용할 수 있습니다.

V2 마이그레이션 보안 체크리스트

  • Recipient allowlists configured for every API endpoint your agent calls → 에이전트가 호출하는 모든 API 엔드포인트에 대해 수신자 허용 목록이 구성됨
  • Chain allowlist set — only chains your agent’s wallet is funded on → 체인 허용 목록 설정 — 에이전트 지갑이 자금을 보유한 체인만 허용
  • Session TTLs defined — 15–30 minutes for most agent workloads → 세션 TTL 정의 — 대부분의 에이전트 작업에 대해 15~30분
  • Session budget caps enforced — max spend per session, not just per transaction → 세션 예산 상한 적용 — 트랜잭션당이 아니라 세션당 최대 지출
  • Plugin versions pinned — exact versions, no semver ranges, provenance checked → 플러그인 버전 고정 — 정확한 버전, semver 범위 없음, 출처 확인
  • Monitoring rules updated — both PAYMENT-* and legacy X-PAYMENT-* header patterns → 모니터링 규칙 업데이트 — PAYMENT-* 및 레거시 X-PAYMENT-* 헤더 패턴 모두
  • CAIP identifier validation — reject unknown chain/asset combinations → CAIP 식별자 검증 — 알 수 없는 체인/자산 조합 거부
  • Daily spend limits active — global and per‑route → 일일 지출 한도 활성화 — 전역 및 라우트별
  • New recipient alerting enabled — flag first‑seen payTo addresses → 신규 수신자 알림 활성화 — 처음 본 payTo 주소 표시
  • Testnet payment blocking — reject any testnet payments in production → 테스트넷 결제 차단 — 프로덕션에서 모든 테스트넷 결제 거부

테스트넷 체인 식별자에 대한 트랜잭션

핵심 요약

x402 V2는 프로토콜에 있어 중요한 도약이다. CAIP 표준화, 동적 라우팅, 모듈식 SDK는 대규모 생산 환경에서 에이전트 결제를 실제로 가능하게 만든다.

하지만 새로운 기능마다 새로운 공격 표면이 생긴다. 동적 payTo는 수신자 조작을 의미한다. 세션은 세션 하이재킹을 의미한다. 플러그인은 공급망 공격을 의미한다. 이것들은 이론적인 것이 아니라 결제 프로토콜에 유연성을 추가함으로써 자연스럽게 발생하는 결과이다.

해결책은 V2를 회피하는 것이 아니다. V2의 유연성에 맞춰 동일하게 세밀한 보안 정책을 적용하는 것이 필요하다.

0 조회
Back to Blog

관련 글

더 보기 »

UX/UI 타이포그래피

Typography란 무엇을 의미할까요? - 어떤 font를 사용할지 - 어느 위치에서 얼마나 크게 할지 - 얼마나 굵게 할지 - 행 간격 - ...

이번 주 상위 7개 추천 DEV 게시물

이번 주 Top 7에 오신 것을 환영합니다. DEV 편집팀이 지난 주에 가장 좋아한 게시물을 직접 선정했습니다. 선정된 모든 저자분들께 축하드립니다.