DEEP DIVE REPORT

Vikunja WebSocket 세션 폐기 우회: 삭제된 세션 토큰의 실시간 알림 수신 조건 점검

SecurityDesk
• 2026.10.14 • 조회 2

개요

개요 인포그래픽
오픈소스 태스크 관리 도구 Vikunja의 WebSocket 실시간 푸시 엔드포인트는 서버 측 세션 상태를 확인하지 않고 인증합니다. 그 결과 세션을 폐기(삭제)해도 해당 토큰으로 이미 수립된 연결은 무기한 라이브 푸시를 계속 수신하고, 삭제된 세션의 토큰으로 새 연결까지 수락됩니다.

  • 이 결함은 GitHub Advisory Database의 GHSA-4hv6-xc92-j86g에 등재되어 있습니다.
  • OSV.dev의 해당 기록 역시 세션 폐기 후에도 라이브 푸시를 계속 수신한다는 요약을 제공합니다.
  • 핵심은 세션 폐기 기능이 WebSocket 경계를 전혀 커버하지 않는 설계 결함이라는 점으로, 권한 회수 절차가 실시간 푸시 경로에서 무력화될 수 있습니다.

영향 범위

영향을 받을 수 있는 환경은 다음입니다.

  • WebSocket 실시간 푸시를 사용하는 Vikunja 배포 환경. 공개 PoC에서 재현이 확인된 기준은 v2.6.0의 SQLite 로컬 배포입니다.
  • 세션을 폐기한 이후에도 액세스 JWT가 유효하거나 유출된 사용자 계정. 이 경우 공격자가 폐기 후에도 해당 계정의 실시간 알림·이벤트 스트림을 지속적으로 수신할 수 있습니다.

다음 사항은 공개 자료에서 확인되지 않은 영역입니다.

  • 패치된 수정 버전 번호
  • 다른 Vikunja 버전별 취약 여부

공개 증거에는 취약 버전의 정확한 상한과 하한이 명시되어 있지 않습니다. 재현이 확인된 v2.6.0을 기준으로 점검 범위를 설정하되, 정확한 버전 경계는 패치 정보 확인 후 확정해야 합니다.

기술적 분석

사용자 액세스 JWT에는 세션 ID(sid) 클레임이 담겨 있습니다. 일반 API 경로에서는 세션 행이 삭제되면 리프레시 토큰이 올바르게 무효화됩니다. 그러나 WebSocket 엔드포인트는 이 대조 단계를 거치지 않습니다.

  • WebSocket 엔드포인트 GET /api/v2/ws는 첫 클라이언트 메시지를 통해 인증합니다.
  • Connection.handleAuth(pkg/websocket/connection.go:168)는 토큰을 auth.GetUserIDFromToken으로만 검증합니다.
  • 이 과정에서 sid 클레임을 sessions 테이블과 대조하는 단계가 없습니다.
  • 따라서 암호학적으로 유효한 JWT라면 서버가 이미 삭제한 세션의 토큰이라도 통과합니다.

그 결과 폐기 전에 인증된 연결은 폐기 후에도 계속 인증 상태로 유지되어 무기한 푸시를 수신하고, 폐기 이후에도 새 WebSocket 연결이 수락됩니다. TOTP 활성화가 내부적으로 DeleteAllUserSessions을 호출해 모든 세션을 삭제하지만, WebSocket 경로에서는 이 폐기 효과가 반영되지 않는 것이 좋은 예입니다.

공개 PoC·익스플로잇 분석

공개 아카이브에 재현 절차가 포함되어 있어, 이 결함은 추정이 아니라 검증된(PoC 공개) 상태입니다.

  • 출처: GHSA-4hv6-xc92-j86g의 첨부 아카이브. deployment/deploy.sh(로컬 Vikunja v2.6.0, loopback, SQLite)와 poc/poc.sh(poc/poc.py 실행)를 포함합니다.
  • 전제조건: 피해자 계정 등록과 로그인, 이후 상호작용을 위한 제2 사용자 등록, 로컬 loopback SQLite 배포 환경.
  • 입증 범위: 피해자의 WebSocket 인증 후 세션을 삭제하면 기존 연결이 유지되고 삭제된 세션 토큰으로 새 연결까지 수락되는 과정을 재현합니다. 재현은 v2.6.0 기준이며 다른 버전까지 일반화하지 않습니다.
  • 운영상 의미: 이 결함이 실제 운영 환경에서도 성립할 가능성을 보여 줍니다. 다만 조사 범위 내 실제 야생 익스플로잇이나 공격 캠페인 증거는 확인되지 않았으며, 이는 공격이 없다는 뜻이 아니라 공개 확인 부재입니다. 위협 수위 평가는 PoC 공개 수준을 기준으로 하는 것이 적절합니다.

대응 방안

제공된 근거가 확인하는 사실은 WebSocket 엔드포인트가 sid 클레임을 sessions 테이블과 대조하지 않아, 세션이 삭제된 토큰으로 기존 연결이 폐기 후에도 계속 인증되고 새 연결까지 수락된다는 점입니다. 공개 근거에 따르면 TOTP 활성화 시 DeleteAllUserSessions이 호출되어 모든 세션이 폐기되지만, 이 WebSocket 실시간 푸시 경로에서는 해당 폐기가 반영되지 않습니다.

즉시 수행: 확인과 업그레이드 판단

따라서 운영자는 해당 경로에서 세션 폐기가 무력화될 수 있다는 점을 기준으로, 패치된 수정 버전이 확인되는 대로 즉시 업그레이드하는 것을 우선하는 것이 타당합니다.

이후 확인: 패치 정보, 버전 범위, 등급화 한계

  • 현재 공개 증거에는 수정 버전 번호나 패치 커밋이 명시되어 있지 않으므로, 업스트림 릴리스에서 패치 정보를 확인한 후 적용 여부를 결정해야 합니다.
  • 패치 버전 번호가 공개 증거에 없으므로, 적용 대상 버전과 업그레이드 목표 버전을 업스트림 공지 기준으로 확정해야 합니다.
  • CVE 번호와 CVSS 심각도 점수도 공개 증거에 포함되어 있지 않아, 위험 등급화와 티켓 우선순위 산정 시 이 한계를 반영해야 합니다.
  • 이 결함에 특화된 로그 시그니처나 IOC, 폐기된 세션의 WebSocket 연결을 식별하는 벤더 권고도 제공된 근거에 없습니다. 이 영역은 공개 확인 부재 상태로 봐야 하며, 이 부재가 공격이 없다는 뜻은 아닙니다.

참고자료

함께 읽으면 좋은 글

본 콘텐츠는 AI 기술로 작성된 분석 리포트를 포함하고 있습니다. 내용 중 사실과 다르거나 보완이 필요한 정보를 발견하셨으면 댓글을 통해 의견을 부탁드립니다. 여러분의 피드백은 더 정확한 보안 정보 공유에 큰 도움이 됩니다.

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

로그인

아직 댓글이 없습니다.

첫 번째 댓글을 작성해보세요!

IT 도구 서랍

→ Unix: 2025-01-15T09:30:00
→ 날짜: 1736934600

→ ASCII: ABC
→ 문자: 65 66 67

ASCII 코드표 — 클릭하면 입력란에 추가

DecHex약어설명
DecHex문자
DecHex문자

→ 유니코드: 홍길동
→ 문자: \ud64d\uae38\ub3d9