
Proof-of-concept demonstrating stored XSS in Appsmith Table Widget leading to vertical privilege escalation and full admin takeover via XSS-to-CSRF attack.
Appsmith의 저장형 XSS를 통한 권한 상승 PoC(Proof-of-Concept)
공개 정보: 원래 GHSA-5hw4-whxv-6794를 통해 저자가 보고함
⚠️ 승인된 침투 테스트/연구 용도로만 사용하십시오.
| 필드 | 값 |
|---|---|
| CVE ID | CVE-2026-30862 |
| 심각도 | 🔴 치명적(Critical) |
| CVSS 점수 | 9.1 |
| CVSS 벡터 | [CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H] |
| CWE | CWE-79, CWE-269, CWE-352 |
| 영향받는 제품 | Appsmith ≤ 1.95 |
| 패치 버전 | 1.96 |
| 권고 | GHSA-5hw4-whxv-6794 |
Table Widget(TableWidgetV2)에 치명적 저장형 XSS 취약점이 존재합니다. 근본 원인은 React 컴포넌트 렌더링 파이프라인에서 HTML 삭제(sanitization)가 부재하여 악성 속성이 DOM에 삽입될 수 있다는 점입니다. "사용자 초대(Invite Users)" 기능을 활용하여 일반 사용자 계정([email protected])을 가진 공격자는 시스템 관리자로 하여금 고권한 API 호출(/api/v1/admin/env)을 실행하도록 강제할 수 있으며, 이로 인해 완전한 관리자 계정 탈취가 발생합니다.
1. 근본 원인: 출력 삭제(Output Sanitization) 싱크 부재 이 취약점은 Table Widget의 렌더링 엔진에 존재합니다.
파일: app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.tsx
BasicCell 컴포넌트는 columnType이 URL 또는 Plain Text로 설정된 경우 데이터를 삭제하지 못합니다. 사용자가 제공한 원시 값을 React 자식 요소로 직접 반환하며, 브라우저는 이를 실행 가능한 HTML로 해석합니다.
취약한 코드 스니펫(132-143행 및 172-173행):
const contentToRender = useMemo(() => {
switch (columnType) {
case ColumnTypes.URL:
// 삭제 없이 'url'을 href에 직접 삽입
return <a href={url} target="_blank">{value}</a>;
default:
return value; // 141행: 원시 값 반환
}
}, [columnType, url, value]);
// 173행: 삭제되지 않은 콘텐츠가 DOM에 주입되는 최종 싱크
<Content ref={contentRef}>{contentToRender}</Content>
2. 공격 벡터: 사회공학을 통한 XSS-to-CSRF(초대 기능) SESSION 쿠키는 HttpOnly로 보호되지만, XSRF-TOKEN은 document.cookie를 통해 접근할 수 있습니다. Appsmith는 모든 사용자가 자신의 앱에 다른 사용자를 "초대"할 수 있도록 허용하므로, 공격자는 이를 전달 메커니즘으로 사용하여 관리자의 활성 세션 내에서 교차 권한 요청 위조(CPRF) 를 실행할 수 있습니다.
1단계: XSS 취약점 검증
일반 사용자 계정으로 로그인합니다: [email protected].
새 애플리케이션을 만들고 Table Widget을 추가합니다.
Table Data 속성에 다음을 주입합니다:
[{ "id": 1, "payload": "" }]
-- 2단계: 무기화(완전한 관리자 탈취)
[email protected]으로 로그인한 상태에서 관리 환경을 수정하도록 설계된 다음 페이로드로 Table Data를 업데이트합니다:[
{
"id": 1,
"Status": "System Update Required",
"payload": "alert('Admin Privileges Granted to [email protected]'));\">"
}
]
"공유(Share)" 기능을 사용하여 시스템 관리자([email protected])를 앱에 초대합니다. 이렇게 하면 관리자가 초대를 열 때 악성 테이블을 보게 됩니다.
관리자가 앱을 실행하면 스크립트가 백그라운드에서 실행됩니다. 관리자의 XSRF-TOKEN을 읽고 PUT 요청을 보내 [email protected]을 관리자 화이트리스트에 추가합니다.
결과: [email protected]으로 다시 로그인합니다. 이제 관리자 설정(Admin Settings) 및 모든 인스턴스 구성에 대한 전체 액세스 권한을 갖게 됩니다.
취약점 유형: 저장형 XSS / 수직적 권한 상승.
심각도: 9.1(치명적) | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H
위험: Appsmith 인스턴스의 완전한 손상. 공격자는 민감한 환경 변수, 데이터베이스 자격 증명에 접근하고 인스턴스 내의 모든 애플리케이션을 수정할 수 있습니다.
싱크 삭제(Sanitize Sinks): BasicCell.tsx 및 관련 컴포넌트의 모든 동적 출력을 DOMPurify.sanitize()로 래핑합니다.
강화된 CSP: XSS 페이로드에서 관리 엔드포인트로의 무단 API 호출을 방지하기 위해 엄격한 connect-src 정책을 구현합니다.
https://github.com/user-attachments/assets/206a10e4-1619-4887-a552-99761baa0a29