
CVE-2026-39987에 대한 개념 증명 익스플로잇으로, Marimo의 /terminal/ws WebSocket 엔드포인트에서 발생하는 인증 전 RCE 취약점이며 자격 증명 없이 대화형 셸을 획득할 수 있습니다.
CVSS 4.0: 9.3 (Critical) · AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H
영향: marimo <= 0.20.4 · 패치됨: 0.23.0 · CWE-306 (인증 누락)
권고: GHSA-2679-6mx9-h9xc · 수정: marimo-team/marimo@c24d480
WebSocket 엔드포인트 /terminal/ws (marimo/_server/api/endpoints/terminal.py)는
연결을 수락하고 pty.fork()를 호출하기 전에 세션 모드(EDIT)와 플랫폼 지원만
확인합니다. @requires(...) 데코레이터도, validate_auth() 호출도 포함하지
않습니다.
0.20.4에서 측정한 대조:
@requires(...) 73회 사용./ws (notebook) -> validate_auth() 2회 호출.terminal.py -> @requires 0회, validate_auth 0회. <-- 결함.AuthBackend 미들웨어는 HTTP와 /ws 웹소켓을 보호하지만, /terminal/ws는
쿠키도 토큰도 없이 연결을 수락하고 marimo 프로세스의 권한으로 PTY 셸을
포크합니다.
marimo edit ...), 이는 편집기의 기본 모드입니다.pty를 지원하는 플랫폼 (Linux/macOS; Windows와 Pyodide는 영향받지 않음).네트워크를 통해 marimo edit 서버에 도달할 수 있는 공격자(원격 / 컨테이너
배포에서 흔하며, 종종 root로 실행됨)는 인증 없이 대화형 셸을 얻습니다:
자격 증명 탈취(cat .env), 측면 이동, 악성코드 배포. 공개 후 10시간 이내에
실제 공격에 악용되었으며, 2026-04-23에 CISA의 KEV 카탈로그에 추가되었습니다.
pip install "marimo==0.20.4" websockets
marimo edit demo.py --headless --port 2718 --token --token-password SECRET
python exploit.py ws://127.0.0.1:2718 "id; cat /etc/passwd"
exploit.py는 토큰도, 쿠키도, Authorization 헤더도 보내지 않습니다. 명령을
원시 텍스트 + "\r"(Enter)로 전송하며, 이는 사용자가 터미널에 입력하는 방식과
정확히 동일합니다.
/ws -> 403 (인증이 실제로 작동함)./terminal/ws -> 수락됨. 서버에서 실행됨:
uid=1000() gid=1000() ...
Linux ...
그리고 /tmp/cve_2026_39987_proof.txt를 작성함 -> RCE 확인.marimo >= 0.23.0으로 업그레이드하십시오. 임시 완화책: marimo edit를
신뢰할 수 없는 네트워크에 노출하지 마십시오; 편집기를 인증된 프록시 뒤에
배치하십시오; 비밀 정보 없이 비권한 / 컨테이너에서 실행하십시오.
승인된 보안 테스트 및 교육 목적으로만 사용하십시오. 소유하거나 테스트에 대한 명시적 허가를 받은 시스템에만 실행하십시오.