
CVE-2026-39275 - Cockpit CMS의 저장된 XSS로 인한 계정 탈취
| CVE ID | CVE-2026-39275 |
| 취약점 | 저장형 크로스 사이트 스크립팅 (XSS) → 계정 탈취 |
| CWE | CWE-79 |
| 영향을 받는 버전 | Cockpit CMS <= 2.13.5 |
| 패치된 커밋 | d70dc50 |
| CVSS 3.1 | 8.4 (AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N) |
| 제보자 | Rohith - SecurifyAI의 보안 컨설턴트 |
콘텐츠 컬렉션 목록 보기의 저장형 XSS 취약점으로 인해 콘텐츠 쓰기 액세스 권한이 있는 모든 사용자(API 키 또는 인증된 편집자 세션)가 영향을 받는 컬렉션의 항목 목록을 보는 모든 관리자 또는 편집자의 브라우저에서 실행되는 임의의 JavaScript를 주입할 수 있습니다.
Cockpit의 세션 토큰은 JavaScript에서 완전히 접근 가능합니다. 세션 쿠키는 HttpOnly 플래그 없이 설정되며, CSRF JWT는 전역 App.csrf 변수와 <html>의 data-csrf 속성에 노출됩니다. 이를 통해 주입된 스크립트가 두 토큰을 읽고 외부로 재전송하여 CSRF 보호를 무력화하고 완전한 세션 하이재킹 및 계정 탈취를 가능하게 합니다.
필드 render() 출력이 출력 인코딩 없이 Vue의 v-html 지시문에 전달됩니다.
| 파일 | 라인 | 역할 |
|---|---|---|
modules/App/assets/vue-components/fields/field-tags.js | 25 - 34 | 태그 렌더러 - 인코딩 없음 |
modules/App/assets/vue-components/fields/field-select.js | 26 | 선택 렌더러 - 인코딩 없음 |
modules/Content/views/collection/items.php | 149 | v-html 싱크 |
curl -X POST "http://localhost:8080/api/content/item/posts" \
-H "Content-Type: application/json" \
-H "api-key: USR-<attacker-api-key>" \
-d '{
"data": {
"title": "Innocent Looking Post",
"tags": [
"",
""
],
"body": "Just a regular post.",
"_state": 1
}
}'
관리자 또는 편집자가 /content/collection/items/posts로 이동합니다. 태그 렌더러가 저장된 문자열을 반환하고, v-html이 이를 실제 `` 요소로 구문 분석하며, 가짜 src가 실패하여 onerror 핸들러가 실행됩니다.
이제 두 토큰 모두 읽을 수 있습니다. 세션 쿠키는 document.cookie를 통해, CSRF JWT는 App.csrf / document.documentElement.getAttribute('data-csrf')를 통해 읽을 수 있습니다. 무기화된 페이로드가 둘 다 유출합니다:

공격자는 도난당한 쿠키와 CSRF 토큰을 재전송하여 완전히 인증된 관리자 액세스 권한을 얻고, 관리자 계정을 생성하거나 자격 증명을 변경하거나 콘텐츠를 수정할 수 있습니다.
낮은 권한의 편집자(또는 콘텐츠 쓰기 API 키 보유자)가 전체 관리자로 권한 상승합니다. 페이로드가 저장되어 목록을 보는 모든 관리자/편집자에게 실행되므로 지속적이고 다중 피해자 손상이 발생합니다.
주요 수정 - 기존 App.utils.stripTags() 헬퍼를 사용하여 v-html에 도달하기 전에 렌더 출력을 삭제합니다.
field-tags.js:
value = App.utils.stripTags(value); // sanitize before v-html
field-select.js:
return App.utils.stripTags(value); // sanitize before v-html
심층 방어 - 세션 쿠키 강화:
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1); // over HTTPS
ini_set('session.cookie_samesite', 'Strict');
HttpOnly만으로는 충분하지 않습니다. XSS는 여전히 피해자의 인증된 브라우저 컨텍스트 내에서 작동할 수 있으므로 출력 인코딩이 필수적인 수정입니다.
| 날짜 | 이벤트 |
|---|---|
| 2026-03-29 | 취약점을 Cockpit CMS 유지관리자에게 보고 |
| 2026-03-29 | 유지관리자가 수정 사항 출시 |
| 2026-04-04 | CVE 요청됨 |
| 2026-06-23 | CVE-2026-39275 할당됨 |
<pub date> | 공개 공개 |
이 자료는 조정된 공개 이후 교육 및 방어 목적으로 게시됩니다. 자신이 소유하거나 명시적으로 테스트 권한이 있는 시스템에만 사용하십시오.