SK쉴더스 로고
ADT캡스캡스홈
SK쉴더스

Network-AI MCP 인증 결함 분석 및 취약점 제보 사례 (CVE-2026-42856)

EQST Now | 2026.05.14

NOW Briefing

Brief 1 EQST는 npm 패키지 network-ai(Jovancoding/Network-AI) 5.1.2 이하 버전에서 MCP HTTP 트랜스포트 인증 누락 취약점인 CVE-2026-42856(CWE-306)을 발견해 제보했습니다.
Brief 2 이 취약점은 MCP HTTP 엔드포인트가 기본적으로 모든 네트워크 인터페이스에서 요청을 수신하는 동시에, 도구 호출 요청에 대한 인증 검사를 수행하지 않아 발생합니다. 따라서 네트워크에서 접근 가능한 공격자가 관리자 권한이 필요한 기능을 인증 없이 실행할 수 있습니다.
Brief 3 운영자는 5.1.3 이상으로 즉시 업그레이드하고, MCP 엔드포인트의 외부 노출 여부와 감사 로그 내 비정상적인 도구 호출 이력을 함께 점검해야 합니다.

Network-AI MCP 인증 결함 분석 및 취약점 제보 사례 (CVE-2026-42856)

※ 본 문서에서 다루는 CVE-2026-42856은 EQST가 자체 연구를 통해 발견 및 제보하여 등록된 취약점입니다.

■ 개요

Jovancoding/Network-AI는 TypeScript와 Node.js 기반의 멀티 에이전트 오케스트레이터입니다. 외부 클라이언트는 MCP(Model Context Protocol)의 HTTP 트랜스포트를 통해 이 시스템의 도구를 호출할 수 있습니다. EQST는 해당 취약점을 발견해 2026년 4월 24일 GitHub Security Advisory(GHSA-fj4g-2p96-q6m3)로 제보했으며, 5월 11일 CVE-2026-42856으로 정식 등록됐습니다.

핵심 문제는 MCP HTTP 엔드포인트가 외부 요청을 수신할 때 인증, 세션, 오리진, 토큰 검사를 수행하지 않고 JSON-RPC 요청을 그대로 처리한다는 점입니다. 여기에 기본 바인드 주소가 0.0.0.0으로 설정되어 있어, 서비스가 서버의 모든 네트워크 인터페이스에서 요청을 수신하는 구조였습니다.

방화벽이나 접근 제어가 제대로 적용되지 않은 환경에서는 외부 공격자가 MCP 엔드포인트에 접근해 관리자용 도구를 직접 호출할 수 있습니다. 이 경우 설정 변경, 에이전트 제어, 토큰 발급·취소 같은 작업이 모두 가능합니다.

결론적으로 이번 취약점은 관리 기능으로 이어지는 HTTP 엔드포인트가 외부에 열릴 수 있는 구조에서, 요청에 대한 인증 검사가 전혀 없어 발생했습니다. 운영자는 취약 버전을 5.1.3 이상으로 업그레이드하고, MCP 엔드포인트 노출 여부와 호출 이력을 함께 확인해야 합니다.

■ 요약

항목 내용
CVE ID CVE-2026-42856(Network-AI MCP HTTP 인증 누락)
CVSS 점수 공식 CVSS 점수 미공개
취약점 유형 CWE-306: 중요 기능에 대한 인증 누락
영향/위험 - 인증 없이 관리자 권한이 필요한 도구 호출 가능
- 런타임 구성 변경(config_set) 및 트레이싱·예산 정책 조작
- 보안 토큰 발급·취소(token_create/token_revoke)
- 에이전트 제어(agent_spawn/agent_stop)와 블랙보드 변조
취약 버전 npm network-ai 5.1.2 이하(검증 커밋 c344f205…)
패치 버전 5.1.3 이상

■ 기술 분석

취약점이 시작되는 지점은 HTTP 트랜스포트의 POST 핸들러입니다. lib/mcp-transport-sse.ts:379_handlePost()는 JSON-RPC 본문을 파싱한 뒤, 인증 검사 없이 this._bridge.handleRPC(rpc)를 호출합니다. 이어서 lib/mcp-transport-sse.ts:155handleRPC()tools/call 요청을 도구 레지스트리의 call(toolName, toolArgs)로 곧바로 전달합니다. 이 두 경로 어디에도 권한을 검사하는 단계(인가 게이트)가 없어, 외부에서 임의의 도구를 바로 호출할 수 있습니다.

아래 코드는 실제 취약 라인과 호출 흐름을 기준으로 재구성한 축약 코드입니다. 핵심은 HTTP 요청이 들어온 뒤 인증·세션·오리진·토큰 검증 없이 JSON-RPC 요청이 브리지로 전달되고, 이후 tools/call이 도구 레지스트리 호출로 이어진다는 점입니다.

// lib/mcp-transport-sse.ts:379
// HTTP POST 본문을 파싱한 뒤, 인증·인가 검증 없이
// MCP bridge로 그대로 전달한다.
async _handlePost(req, res) {
  const rpc = JSON.parse(await readBody(req));

  // 누락된 검증 항목:
  // - Authorization 헤더 확인
  // - 세션 / Origin 검증
  // - Bearer 토큰 또는 공유 시크릿 확인
  const result = await this._bridge.handleRPC(rpc);

  res.writeHead(200, { "Content-Type": "application/json" });
  res.end(JSON.stringify(result));
}

// lib/mcp-transport-sse.ts:155
// tools/call 요청이 provider로 직접 전달된다.
async handleRPC(rpc) {
  if (rpc.method === "tools/call") {
    const toolName = rpc.params?.name;
    const toolArgs = rpc.params?.arguments ?? {};

    return this._provider.call(toolName, toolArgs);
  }
}

// lib/mcp-tools-control.ts:231
// 관리자 권한이 필요한 도구가 실행 중인 런타임 설정을 직접 변경한다.
config_set({ key, value }) {
  const parsed = parseConfigValue(value);
  const previous = this._config[key];

  this._config[key] = parsed;

  return {
    ok: true,
    tool: "config_set",
    data: { key, previous, current: parsed, applied: true }
  };
}

도구 계층 역시 호출자 신원을 확인하지 않습니다. lib/mcp-tools-control.ts:231config_setthis._config[key] = parsed 형태로 실행 중인 설정값을 즉시 변경합니다. config_get이나 agent_list 같은 조회 전용 도구도 마찬가지로 인증 없이 외부에 노출됩니다. 여기에 bin/mcp-server.ts:75의 기본 바인드가 0.0.0.0이라는 점까지 더해지면, 컨테이너 포트 매핑이나 허술한 클라우드 보안 그룹 설정만으로도 관리 평면이 외부에 그대로 열릴 수 있습니다.

📌 NOTE

MCP HTTP 트랜스포트는 같은 호스트 안에서만 통신하는 로컬 루프백(127.0.0.1)을 전제로 설계됩니다.

기본값이 0.0.0.0이면 운영자가 의도하지 않은 인터페이스까지 노출되기 쉽습니다.

특히 컨테이너·쿠버네티스 환경에서는 포트 매핑이나 서비스 설정만으로도 외부 접근 경로가 열릴 수 있어 위험이 더 큽니다.

■ PoC

EQST는 제보 과정에서 로컬 도커 환경(http://localhost:13001)을 대상으로, 인증 헤더 없이 관리자 권한이 필요한 도구를 연쇄 호출할 수 있음을 확인했습니다. 검증은 도구 목록 조회(GET /tools) → config_get으로 현재 값 확인 → config_set으로 런타임 값 변경 → 다시 config_get으로 변경 반영 확인 순서로 진행했습니다.

아래는 인증 헤더 없이 defaultTimeout 값을 변경하는 요청과 응답 일부입니다.

# 인증 헤더 없이 config_set 호출
curl http://localhost:13001/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"config_set","arguments":{"key":"defaultTimeout","value":"12345"}}}'

# 응답(result.content[0].text 디코딩):
# {"ok":true,"tool":"config_set","data":{"key":"defaultTimeout","previous":30000,"current":12345,"applied":true}}

⚠️ WARN

위 PoC는 취약점 검증 과정에서 사용한 명령입니다.

본인 소유가 아닌 시스템에서 실행하면 법적 책임이 발생할 수 있으므로, 반드시 격리된 테스트 환경에서만 재현해야 합니다.

■ 탐지 및 점검

✅ CHECK

우선 설치된 network-ai 버전과 MCP 서버 포트의 바인드 주소부터 확인합니다.

npm ls network-ai 또는 package.json을 확인해 5.1.2 이하 버전이 사용 중인지 점검합니다.

ss -tnlp 또는 netstat -tnlp로 MCP 서버 포트가 0.0.0.0에 바인드되어 있는지 확인합니다.

/mcp/tools 엔드포인트가 외부 네트워크에서 접근 가능한 상태인지 스캐닝을 통해 확인합니다.

• 감사 로그(./data/audit_log.jsonl)에서 비정상적인 config_set·token_create·token_revoke 호출 이력을 검색합니다.

• 액세스 로그에서 POST /mcp 요청 중 Authorization 헤더가 없는 호출 패턴을 추출합니다.

■ 대응 방안

💡 TIP

우선순위는 ① 5.1.3 이상으로 업그레이드 → ② 외부 노출 차단 및 바인드 주소 변경 → ③ 도구 단위 권한 검사·접근 통제 강화 순으로 적용합니다.

network-ai를 5.1.3 이상으로 즉시 업그레이드하고, 의존 서비스의 lockfile과 컨테이너 이미지에도 반영되도록 재빌드합니다.

• 패치 적용까지 시간이 필요한 환경에서는 바인드 주소를 127.0.0.1로 변경하거나, 컨테이너 포트 매핑을 내부 네트워크로만 한정합니다.

• 리버스 프록시, VPN, mTLS(상호 TLS 인증) 같은 외부 접근 통제 계층을 추가해, 허가되지 않은 출처에서 MCP 엔드포인트에 접근하지 못하도록 차단합니다.

• 상태를 변경하는 도구(config_set, agent_spawn/agent_stop, token_create/token_revoke, budget_set_ceiling, blackboard_write/blackboard_delete)에는 호출자 신원을 확인하는 인가 검사를 추가합니다.

• 감사 로그 보존 기간과 무결성 정책을 점검해, 의심스러운 호출이 발생했을 때 사후 추적이 가능한지 확인합니다.

[참고 자료]

GitHub Security Advisory GHSA-fj4g-2p96-q6m3

Jovancoding/Network-AI GitHub Repository

NVD - CVE-2026-42856

CWE-306: Missing Authentication for Critical Function

  • #EQST_NOW
  • #취약점
  • #취약점제보

관련 서비스

더 많은 보안 인사이트

SK쉴더스 유튜브 채널에서 확인하세요.

SK쉴더스 유튜브 채널에서 확인하세요.
보안 트렌드와 대응방법

매월 뉴스레터로 확인하세요.

매월 뉴스레터로 확인하세요.