
Laboratoire basé sur Docker pour reproduire la CVE-2026-42647, une injection SQL aveugle basée sur le temps non authentifiée dans le plugin JoomSport WordPress via le paramètre sortf. Inclut des cibles vulnérables et corrigées à des fins de comparaison.
sortf dans JoomSportCe dépôt contient un laboratoire Docker local pour reproduire et valider CVE-2026-42647, une vulnérabilité d'injection SQL non authentifiée affectant le plugin WordPress JoomSport - for Sports: Team & League, Football, Hockey & more.
Le comportement vulnérable se produit dans la fonctionnalité de tri de la liste des joueurs. Un visiteur public peut contrôler le paramètre de requête sortf, qui est utilisé pour construire une clause SQL ORDER BY. Dans les versions vulnérables, la valeur est nettoyée comme du texte et entourée de guillemets inversés, mais elle n'est pas validée par une liste blanche stricte avant d'être ajoutée à la requête SQL.
Ce laboratoire compare deux versions de JoomSport :
| Service | Version JoomSport | But | URL |
|---|---|---|---|
vuln | 5.7.6 | Cible de comparaison vulnérable | http://localhost:8081 |
patched | 5.7.8 | Cible de comparaison patchée | http://localhost:8082 |
Les avis publics identifient les versions antérieures à 5.7.8 comme affectées et la version 5.7.8 comme la version corrigée. Ce laboratoire utilise la version 5.7.6 comme cible vulnérable car un tag source 5.7.7 n'était pas disponible dans le listing des tags SVN du plugin WordPress.org au moment de la préparation de ce laboratoire.
La chaîne de vulnérabilité démontrée est :```text Unauthenticated visitor → JoomSport season player list route → attacker-controlled sortf parameter → unsafe dynamic ORDER BY construction → SQL expression execution → measurable database delay in vulnerable version → patched version rejects the injected sort field and falls back to a safe allowlisted field
Ce laboratoire valide la vulnérabilité en tant qu'injection SQL aveugle basée sur le temps. Il n'effectue pas de vidage de base de données, d'extraction d'identifiants, de modification de données ou d'opérations SQL destructrices.
Ce laboratoire est conçu uniquement pour la recherche locale contrôlée, la compréhension au niveau du code source et la démonstration de portfolio.
## Faits vérifiés
| Affirmation | Preuve | Comment vérifier dans ce laboratoire |
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| JoomSport avant la version 5.7.8 est signalé comme vulnérable à une injection SQL non authentifiée. | Les avis publics identifient JoomSport `< 5.7.8` / `<= 5.7.7` comme affecté. | Consultez la section Références et comparez les services vulnérables/corrigés. |
| JoomSport 5.7.8 est la version corrigée. | Les avis publics et la comparaison des sources montrent que la version 5.7.8 valide la valeur `sortf` avant de construire l'expression de tri. | Inspectez `class-jsport-playerlist.php` dans les deux versions. |
| Le paramètre affecté est `sortf`. | Le code vulnérable de la liste des joueurs lit `classJsportRequest::get('sortf')`. | Exécutez le PoC et observez la requête `sortf` injectée. |
| Le code vulnérable construit une valeur de tri SQL dynamique à partir de l'entrée utilisateur. | Dans la version vulnérable, `sortf` est utilisé pour construire `$options['ordering']`. | Inspectez `sportleague/classes/objects/class-jsport-playerlist.php`. |
| Le point d'insertion SQL est une clause `ORDER BY`. | La valeur générée `$ordering` est ensuite ajoutée à une requête SQL avec `ORDER BY`. | Inspectez `sportleague/base/wordpress/classes/class-jsport-getplayers.php`. |
| Le correctif utilise une correction de type liste blanche. | La version corrigée introduit des colonnes statiques autorisées et des motifs de champ dynamique attendus avant d'utiliser le champ de tri. | Comparez les sources de JoomSport 5.7.6 et 5.7.8. |
| Le laboratoire démontre une injection SQL aveugle basée sur le temps. | La cible vulnérable retarde lorsqu'une expression `SLEEP()` injectée est utilisée ; la cible corrigée ne le fait pas. | Exécutez `python3 poc/poc.py http://localhost:8081 http://localhost:8082`. |
## Hypothèses et inconnues
Ce laboratoire utilise JoomSport 5.7.6 comme cible de comparaison vulnérable car la version corrigée publique est 5.7.8 et qu'un tag source 5.7.7 n'était pas disponible dans la liste des tags SVN du plugin WordPress.org lorsque le laboratoire a été préparé.
Le laboratoire ne prétend pas que 5.7.6 est la seule version vulnérable. Il est utilisé comme une base vulnérable reproductible pour comparer le comportement vulnérable au comportement corrigé de 5.7.8.
Le laboratoire se concentre sur le paramètre `sortf` dans le flux de tri de la liste des joueurs.
L'impact démontré est une injection SQL aveugle basée sur le temps. Le laboratoire ne démontre pas :
* vidage direct de base de données,
* extraction d'identifiants,
* contournement d'authentification,
* élévation de privilèges,
* modification arbitraire de données,
* exécution de code à distance,
* persistance,
* rappels externes,
* ou d'attaques contre des systèmes hors laboratoire.
Un comportement basé sur les erreurs ou booléen peut être possible selon le comportement de la base de données, la configuration de l'application et les différences de réponse, mais ce laboratoire ne repose pas sur ces techniques. La preuve principale est basée sur le temps.
## Résumé de la cause racine
La cause racine est la construction non sécurisée d'une clause `ORDER BY` SQL dynamique à partir du paramètre de requête `sortf`.
Le chemin de code vulnérable commence dans :```text
sportleague/classes/objects/class-jsport-playerlist.php
Dans la logique de chargement de la liste des joueurs, JoomSport lit le paramètre de requête :```text sortf
et l'utilise pour construire:```text
$options['ordering']
Le motif de source vulnérable pertinent est :```php
if (classJsportRequest::get('sortf')) {
$typeAD = in_array(classJsportRequest::get('sortd'), array("ASC","DESC")) ? classJsportRequest::get('sortd') : "ASC";
$options['ordering'] = str_replace(" ","",sanitize_text_field("".classJsportRequest::get('sortf')."")).' '.$typeAD;
}
Le problème ne vient pas principalement du paramètre `sortd`. La valeur de `sortd` est limitée à :```text
ASC
DESC
Le problème est le paramètre sortf car il contrôle la position de l'identifiant/expression SQL utilisée pour le tri.
L'expression dangereuse est :```php
"".classJsportRequest::get('sortf').""
Le code place une entrée contrôlée par l'attaquant dans un contexte d'identifiant MySQL, puis la transmet comme fragment d'ordre SQL.
Le code applique :```php
sanitize_text_field()
mais sanitize_text_field() n'est pas une validation d'identifiant SQL. Il est conçu pour nettoyer du texte, pas pour construire en toute sécurité une syntaxe SQL.