
Laboratorio basato su Docker per riprodurre CVE-2026-42647, una SQL injection cieca basata sul tempo non autenticata nel plugin WordPress JoomSport tramite il parametro sortf. Include target vulnerabili e patchati per il confronto.
sortfQuesto repository contiene un laboratorio Docker locale per riprodurre e validare la CVE-2026-42647, una vulnerabilità di SQL injection non autenticata che interessa il plugin WordPress JoomSport - for Sports: Team & League, Football, Hockey & more.
Il comportamento vulnerabile si verifica nella funzionalità di ordinamento dell'elenco dei giocatori. Un visitatore pubblico può controllare il parametro di query sortf, che viene utilizzato per costruire una clausola SQL ORDER BY. Nelle versioni vulnerabili, il valore viene sanificato come testo e racchiuso tra backtick, ma non viene verificato contro una allowlist rigorosa prima di essere aggiunto alla query SQL.
Questo laboratorio confronta due versioni di JoomSport:
| Servizio | Versione JoomSport | Scopo | URL |
|---|---|---|---|
vuln | 5.7.6 | Obiettivo vulnerabile di confronto | http://localhost:8081 |
patched | 5.7.8 | Obiettivo corretto di confronto | http://localhost:8082 |
Gli advisory pubblici identificano le versioni precedenti alla 5.7.8 come vulnerabili e la 5.7.8 come versione corretta. Questo laboratorio utilizza la 5.7.6 come obiettivo vulnerabile perché un tag sorgente 5.7.7 non era disponibile nell'elenco dei tag SVN del plugin WordPress.org al momento della preparazione di questo laboratorio.
La catena di vulnerabilità dimostrata è:```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
This lab validates the vulnerability as a time-based blind SQL injection. It does not perform database dumping, credential extraction, data modification, or destructive SQL operations.
This lab is designed for controlled local research, source-level understanding, and portfolio demonstration only.
## Verified Facts
| Claim | Evidence | How to verify in this lab |
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| JoomSport before 5.7.8 is reported vulnerable to unauthenticated SQL injection. | Public advisories identify JoomSport `< 5.7.8` / `<= 5.7.7` as affected. | Review the References section and compare the vulnerable/patched services. |
| JoomSport 5.7.8 is the fixed version. | Public advisories and source comparison show that 5.7.8 validates the `sortf` value before building the ordering expression. | Inspect `class-jsport-playerlist.php` in both versions. |
| The affected parameter is `sortf`. | The vulnerable player list code reads `classJsportRequest::get('sortf')`. | Run the PoC and observe the injected `sortf` request. |
| The vulnerable code builds a dynamic SQL ordering value from user input. | In the vulnerable version, `sortf` is used to build `$options['ordering']`. | Inspect `sportleague/classes/objects/class-jsport-playerlist.php`. |
| The SQL sink is an `ORDER BY` clause. | The generated `$ordering` value is later appended into an SQL query with `ORDER BY`. | Inspect `sportleague/base/wordpress/classes/class-jsport-getplayers.php`. |
| The patch uses an allowlist-style fix. | The patched version introduces allowed static columns and expected dynamic field patterns before using the sort field. | Compare JoomSport 5.7.6 and 5.7.8 source. |
| The lab demonstrates time-based blind SQL injection. | The vulnerable target delays when an injected `SLEEP()` expression is used; the patched target does not. | Run `python3 poc/poc.py http://localhost:8081 http://localhost:8082`. |
## Assumptions and Unknowns
This lab uses JoomSport 5.7.6 as the vulnerable comparison target because the public fixed version is 5.7.8 and a 5.7.7 source tag was not available in the WordPress.org plugin SVN tag listing when the lab was prepared.
The lab does not claim that 5.7.6 is the only vulnerable version. It is used as a reproducible vulnerable baseline for comparing vulnerable behavior against the patched 5.7.8 behavior.
The lab focuses on the `sortf` parameter in the player list sorting flow.
The demonstrated impact is time-based blind SQL injection. The lab does not demonstrate:
* direct database dumping,
* credential extraction,
* authentication bypass,
* privilege escalation,
* arbitrary data modification,
* remote code execution,
* persistence,
* external callbacks,
* or attacks against non-lab systems.
Error-based or boolean-based behavior may be possible depending on database behavior, application configuration, and response differences, but this lab does not rely on those techniques. The primary proof is timing-based.
## Root Cause Summary
The root cause is unsafe construction of a dynamic SQL `ORDER BY` clause from the `sortf` request parameter.
The vulnerable code path starts in:```text
sportleague/classes/objects/class-jsport-playerlist.php
Nella logica di caricamento dell'elenco giocatori, JoomSport legge il parametro di richiesta:```text sortf
e lo usa per costruire:```text
$options['ordering']
Il pattern sorgente vulnerabile rilevante è:```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;
}
Il problema non è principalmente il parametro `sortd`. Il valore di `sortd` è limitato a:```text
ASC
DESC
Il problema è il parametro sortf perché controlla la posizione dell'identificatore/espressione SQL utilizzata per l'ordinamento.
L'espressione pericolosa è:```php
"".classJsportRequest::get('sortf').""
Il codice inserisce l'input controllato dall'attaccante in un contesto di identificatore MySQL e poi lo passa come frammento di ordinamento SQL.
Il codice applica:```php
sanitize_text_field()
ma sanitize_text_field() non è una validazione di identificatori SQL. È progettato per pulire il testo, non per costruire in modo sicuro la sintassi SQL.
Il codice vulnerabile racchiude anche il campo di ordinamento controllato dall'utente tra backtick. Tuttavia, i backtick non sono un confine di sicurezza quando l'attaccante può influenzare il contenuto dell'identificatore. Se un attaccante può iniettare un backtick nel valore, può fuoriuscire dal contesto dell'identificatore previsto.