1.Zusammenfassung
Tabellen in ILIAS lassen sich über einen Klick auf die Spaltenüberschrift sortieren. Welche Spalte dabei sortiert werden soll, steht als Wert in der Adresse der Anfrage. Das Tabellen-Framework nahm diesen Wert entgegen und reichte ihn weiter, ohne ihn gegen die tatsächlich vorhandenen Spalten der Tabelle abzugleichen.
Im Papierkorb eines Repository-Containers – also im Papierkorb jedes Kurses, jeder
Gruppe, jeder Kategorie und jedes Ordners – landete dieser ungeprüfte Wert
anschließend in der Datenbankabfrage, die den Inhalt des Papierkorbs lädt. Er wurde
dort ohne Maskierung an die ORDER BY-Klausel angehängt. Wer die Anfrage
verändern konnte, bestimmte damit einen Teil der SQL-Anweisung selbst.
Voraussetzung ist ein angemeldetes Konto mit Schreibrecht auf einem einzigen beliebigen Container. Das ist keine besondere Berechtigung: Jede Person, die irgendwo einen Kurs oder eine Gruppe administriert, besitzt sie. Ein Administrationszugang zur Instanz ist ausdrücklich nicht erforderlich.
2.Betroffene Systeme
Die fehlerhafte Codestelle wurde in allen zum Zeitpunkt der Meldung gepflegten
Versionslinien einzeln überprüft – nicht aus einer Linie auf die anderen geschlossen.
Die Pfade unterscheiden sich zwischen Linie 9 und den späteren Linien lediglich durch
die Umstellung von Services/… auf components/ILIAS/….
| Versionslinie | Betroffen | Behoben in |
|---|---|---|
| ILIAS 9 | alle Stände vor 9.22 | 9.22 |
| ILIAS 10 | alle Stände vor 10.10 | 10.10 |
| ILIAS 11 | alle Stände vor 11.3 | 11.3 |
Die identische Codestelle war darüber hinaus im damaligen Entwicklungsstand der nachfolgenden Hauptversion vorhanden und wurde dort ebenfalls verifiziert. Da dieser Stand zum Zeitpunkt der Meldung nicht als Release verfügbar war, ist er hier nicht als eigene Zeile geführt.
Für die Einschätzung der eigenen Installation ist außerdem hilfreich zu wissen, dass der betroffene Bildschirm nicht nur über den sichtbaren Papierkorb-Reiter erreichbar ist. Der zugehörige Befehl wird von der allgemeinen Befehlsverteilung der Container-Oberfläche entgegengenommen und über das Schreibrecht abgesichert. Die Betroffenheit hängt damit an der Version, nicht an der Konfiguration.
3.Technische Analyse
Voraussetzungen. Ein angemeldetes Konto mit Schreibrecht auf einem einzigen beliebigen Repository-Container – Kurs, Gruppe, Kategorie oder Ordner. Kein Administrationszugang, keine besondere Rolle, keine Nutzerinteraktion auf der Gegenseite. Der betroffene Bildschirm ist der Papierkorb dieses Containers.
Der Einstieg war nicht der Papierkorb. Ich hatte nach Stellen gesucht, an denen eine SQL-Anweisung aus Zeichenketten zusammengesetzt wird, und bin von dort aus rückwärts gelaufen: Woher kommt der Wert, der in die Anweisung wandert? Bei dieser Abfrage führte die Spur bis in die Adresszeile zurück. Die Ursache liegt entsprechend nicht im Papierkorb, sondern eine Ebene tiefer – im gemeinsam genutzten Tabellen-Framework. Der Papierkorb ist nur die Stelle, an der sie sichtbar wird.
Die Sortierangabe wird nie geprüft
Das Framework liest den Navigationsparameter der Tabelle, zerlegt ihn an den Doppelpunkten in Sortierfeld, Sortierrichtung und Offset und übernimmt das Sortierfeld unverändert:
$nav = explode(":", $this->nav_value);
// $nav[0] is order by
$req_order_field = $nav[0] ?? "";
$req_order_dir = $nav[1] ?? "";
$req_offset = (int) ($nav[2] ?? 0);
$this->setOrderField(($req_order_field != "") ? $req_order_field : $this->getDefaultOrderField());
$this->setOrderDirection(($req_order_dir != "") ? $req_order_dir : $this->getDefaultOrderDirection());
Bemerkenswert ist, dass eine passende Positivliste bereits existiert: Jede Tabelle meldet beim Aufbau ihre sortierbaren Spalten an. Der Abgleich gegen diese Liste stand jedoch ausschließlich in dem Zweig, der eine zuvor gespeicherte Sortierung aus der Sitzung wiederherstellt – und entschied dort auch nur über die Richtung. Kam der Wert aus der Anfrage, wurde der Zweig übersprungen und die Liste nie befragt.
Die Sortierrichtung ist demgegenüber sauber: Sie wird auf
asc oder desc normalisiert, alles andere fällt auf
asc zurück. Über die Richtung ließ sich also nichts einschleusen. Offen
war ausschließlich das Feld.
Der Eingabefilter greift hier nicht
Der Wert durchläuft auf dem Weg zur Tabelle die allgemeine Eingabebehandlung. Diese entfernt jedoch nur HTML-Auszeichnung. Anführungszeichen, Klammern, Kommata, Gleichheitszeichen, Kommentareinleitungen und hexadezimale Literale überstehen sie unverändert – für eine Sortierangabe, die als SQL-Ausdruck weiterverarbeitet wird, ist sie damit wirkungslos.
Warum hilft hier kein Platzhalter?
Die übliche Antwort auf SQL-Injection lautet: Werte nicht in die Anweisung schreiben, sondern als Parameter übergeben. Für Spaltennamen funktioniert das nicht. Ein Platzhalter kann einen Bezeichner nicht ersetzen – wer nach einer wählbaren Spalte sortieren will, muss deren Namen in die Anweisung hineinschreiben. Die Sortierklausel ist damit eine der wenigen Stellen, an denen die Standardlösung prinzipiell nicht greift und jedes Projekt sich selbst etwas überlegen muss: in aller Regel eine Positivliste. Das ist keine ILIAS-Eigenheit, sondern gilt für jede Anwendung, die sortierbare Tabellen anbietet.
Der Weg bis zur Datenbank
-
Anfrage
Der Navigationsparameter der Papierkorb-Tabelle trägt den Wert
Feld:Richtung:Offset. Er ist Teil der Adresse und an kein CSRF-Token gebunden. - Tabellen-Framework Das Feld wird ohne Abgleich gegen die angemeldeten Spalten übernommen.
- Papierkorb-Tabelle Diese Tabelle sortiert ausdrücklich in der Datenbank und nicht in PHP. Sie reicht das Feld deshalb an die Abfrageschicht weiter.
-
Abfrageschicht
Dort wird die
ORDER BY-Klausel durch Zeichenkettenverkettung gebildet und die Abfrage ausgeführt.
$order = ' ';
if ($order_field) {
$order = 'ORDER BY ' . $order_field . ' ' . $order_direction;
}
$query = $select . $from . $this->appendTrashNodeForContainerQueryFilter($filter) . $order;
// ...
$res = $this->db->query($query);
Die Filter derselben Abfrage sind korrekt behandelt: Sie laufen über die Maskierungsfunktionen der Datenbankschicht, und der Filter für die löschende Person wird vorher in eine Benutzer-ID aufgelöst. Die Sortierklausel war die einzige offene Stelle in dieser Abfrage – und genau eine genügt.
Der Fix des Herstellers
Der Hersteller hat an der Senke angesetzt: Das Sortierfeld wird als Bezeichner maskiert, die Richtung zusätzlich normalisiert.
$valid_direction = strtolower($order_direction) === 'desc' ? 'DESC' : 'ASC';
$order = 'ORDER BY ' . $this->db->quoteIdentifier($order_field) . ' ' . $valid_direction;
Das schließt diese Stelle zuverlässig. Ergänzend habe ich in der Meldung angeregt, die Sortierangabe zusätzlich bereits im Tabellen-Framework gegen die angemeldeten Spalten zu prüfen. Die Positivliste liegt dort ohnehin vor; sie auch auf dem Weg aus der Anfrage anzuwenden, würde alle Ansichten auf einmal mitnehmen. Dass mehrere ILIAS-Komponenten diese Zuordnung heute schon selbst vornehmen – mit expliziter Abbildung der Spaltennamen und normalisierter Richtung – zeigt, dass die Lösung im Projekt bereits existiert und lediglich zentral verfügbar gemacht werden müsste. Wie ein solcher Umbau gegenüber anderen Aufgaben zu priorisieren ist, kann das Projekt allerdings besser beurteilen als ich.
Warum die Kette gehalten hat
Keiner der folgenden Punkte ist für sich genommen eine Schwachstelle. Erst ihr Zusammentreffen ergibt den Befund – und das ist der Grund, warum eine Stelle wie diese über Jahre unentdeckt bleiben kann:
- Das Tabellen-Framework übernimmt das Sortierfeld aus der Anfrage, ohne es gegen die angemeldeten Spalten abzugleichen.
- Die passende Positivliste existiert im Framework, hängt aber ausschließlich am Zweig für die gespeicherte Sortierung – und damit nicht an dem Weg, auf dem der Wert tatsächlich von außen kommt.
- Die allgemeine Eingabebehandlung entfernt nur HTML-Auszeichnung und lässt genau die Zeichen durch, auf die es in einem SQL-Ausdruck ankommt.
- Die Papierkorb-Tabelle sortiert – anders als viele andere Ansichten – ausdrücklich in der Datenbank und reicht das Feld deshalb bis zur Abfrage durch.
-
Dort wird die
ORDER BY-Klausel als Zeichenkette zusammengesetzt, während die Filter derselben Abfrage sauber maskiert sind. - Der Zugang zu diesem Bildschirm hängt an einer einzigen Bedingung, dem Schreibrecht auf einem Container. Das senkt die nötigen Rechte von „Administration“ auf „irgendwo Kursleitung“.
4.Auswirkung (Impact)
In der ORDER BY-Klausel sind unter MySQL und MariaDB vollwertige
Ausdrücke zulässig, einschließlich Unterabfragen. Damit ist die Klausel kein
eingeschränkter Sonderfall, sondern erlaubt lesenden Zugriff auf den gesamten
Datenbestand – Passwort-Hashes, personenbezogene Daten, Sitzungsdaten,
hinterlegte Schnittstellen-Geheimnisse.
Für die Einstufung kommt ein zweiter Umstand hinzu, der mit dieser Codestelle nichts zu tun hat und den viele PHP-Anwendungen teilen: Die verwendete Datenbankanbindung lässt in ihrer Voreinstellung mehrere Anweisungen pro Aufruf zu. Dadurch bleibt es im ungünstigen Fall nicht bei einem Lesezugriff – möglich sind dann auch schreibende Datenbankoperationen, bis hin zum Überschreiben von Zugangsdaten.
Diesen zweiten Punkt habe ich im Rahmen der Meldung auf eigens dafür aufgesetzten Instanzen mit ausdrücklicher Testfreigabe überprüft – ausschließlich, um die Einstufung als schreibende und nicht bloß lesende Schwachstelle belegen zu können. Für die Meldung war das wichtig, weil davon abhängt, wie dringlich ein Befund eingeordnet wird.
| Metrik | Wert | Begründung |
|---|---|---|
| Angriffsvektor | Netzwerk | Eine gewöhnliche angemeldete HTTP-Anfrage genügt. |
| Komplexität | niedrig | Deterministisch, ein einzelner Parameter, kein Raten, kein Zeitfenster. |
| Benötigte Rechte | niedrig | Schreibrecht auf einem beliebigen Container; kein Administrationszugang. |
| Nutzerinteraktion | keine | Der Angreifer handelt in der eigenen Sitzung. |
| Vertraulichkeit | hoch | Beliebige Leseabfragen über den gesamten Datenbestand. |
| Integrität / Verfügbarkeit | hoch | Schreibende Operationen sind möglich, weil mehrere Anweisungen zulässig sind. |
Ohne die Möglichkeit, mehrere Anweisungen abzusetzen, läge die Bewertung bei 6.9
(Medium) mit
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N. Beide
Werte sind hier angegeben, weil sich der Vektor sonst nicht nachrechnen lässt – und
weil der Abstand zwischen ihnen zeigt, wie stark eine einzelne Voreinstellung der
Datenbankanbindung die Einstufung verschiebt.
Ein Nebeneffekt verlängert die Wirkung: Das Tabellen-Framework merkt sich die zuletzt gewählte Sortierung in den Tabelleneinstellungen des handelnden Kontos. Eine eingeschleuste Sortierangabe wurde deshalb bei jedem weiteren Aufruf dieses Bildschirms erneut ausgeführt, bis sie durch eine gültige Sortierung ersetzt wurde.
Auswirkung in einem Satz: Vollständiger Lesezugriff auf die Datenbank der Instanz für jedes Konto, das irgendwo Schreibrechte hat – und bei der voreingestellten Datenbankanbindung zusätzlich schreibender Zugriff, womit die Übernahme der Instanz in Reichweite liegt.
5.Gegenmaßnahmen / Workarounds
Update
Die maßgebliche und einzige vollständige Maßnahme ist das Update auf ILIAS 9.22, 10.10 oder 11.3. Die Versionen wurden am 12.08.2026 bereitgestellt und enthalten neben dieser Korrektur weitere Sicherheitsbehebungen.
Warum eine Konfigurationsänderung hier nicht genügt
Die Betroffenheit hängt an der eingesetzten Version, nicht an Einstellungen der Instanz – deshalb führt kein Weg an dem Update vorbei. Wer es nicht sofort einspielen kann, kann den Zugriff bis dahin außerhalb der Anwendung begrenzen; die folgenden Punkte sind als Überbrückung gedacht, nicht als Ersatz.
Überbrückung, wenn nicht sofort aktualisiert werden kann
- Filterung am vorgelagerten Webserver. Die Sortierangabe besteht im Normalbetrieb ausschließlich aus einem Spaltennamen. Anfragen, deren Tabellen-Navigationsparameter Zeichen außerhalb von Buchstaben, Ziffern, Punkt und Unterstrich enthalten, lassen sich zurückweisen. Das ist eine Notmaßnahme, kein Ersatz für den Patch.
- Schreibrechte durchsehen. Das ist ohnehin sinnvoll, verringert hier aber unmittelbar den Kreis der Konten, die die Stelle erreichen konnten.
- Mehrfachanweisungen unterbinden. Wo die Betriebsumgebung es zulässt, begrenzt das die Auswirkung einer SQL-Injection generell auf den lesenden Fall – eine allgemeine Härtung, unabhängig von diesem Befund.
Prüfung auf zurückliegende Ausnutzung
Die Schwachstelle wird über die Adresse angesprochen. In den Zugriffsprotokollen des Webservers lässt sich daher gezielt nachsehen:
- Aufrufe mit einem Tabellen-Navigationsparameter, dessen Wert nicht wie ein Spaltenname aussieht – insbesondere mit Klammern, Anführungszeichen, Semikolon, Kommentarzeichen oder auffälliger Länge.
- Aufrufe des Papierkorb-Befehls auf Containern durch Konten, die diesen Bildschirm sonst nie verwenden.
- Datenbankfehler im Anwendungsprotokoll, die zeitlich mit solchen Aufrufen zusammenfallen.
Ergibt sich ein begründeter Verdacht, sollten Zugangsdaten der Konten mit Administrationsrechten erneuert und die Sitzungen invalidiert werden. Wegen des oben beschriebenen Nebeneffekts lohnt zusätzlich ein Blick auf gespeicherte Tabelleneinstellungen: Dort konnte eine eingeschleuste Sortierangabe dauerhaft zurückbleiben.
Hinweis für Betreiber
Bei Fragen zur Betroffenheit der eigenen Installation oder zur Auswertung von Protokolldaten können Sie sich an security@schweigertit.de wenden.
6.Disclosure-Timeline
- Identifikation und Verifikation des Befunds
- Meldung an den Hersteller Mantis 0048128
- Patch durch den Hersteller ILIAS 9.22, 10.10 und 11.3
- Veröffentlichung dieses Advisories
- Veröffentlichung des CVE-Eintrags CVE-2026-82538
7.Referenzen
- CVE CVE-2026-82538 – veröffentlicht am 04.09.2026, CWE-89.
- Hersteller ILIAS open source e-Learning e.V. – Meldung erfasst als Mantis 0048128; Korrektur enthalten in den Releases 9.22, 10.10 und 11.3 vom 12.08.2026.
- CWE CWE-89 (SQL-Injection), beitragend CWE-1236 – unvalidierte Übernahme einer Sortierangabe aus der Anfrage.
- Policy Richtlinie zur verantwortungsvollen Offenlegung von schweigertIT.
- Research Research-Übersicht mit der laufenden CVE-Liste.
Rückfragen zu diesem Advisory
Fragen richten Sie bitte an security@schweigertit.de, gerne verschlüsselt. Proof-of-Concept-Code gebe ich auch auf Anfrage nicht heraus.