LimeSurvey 7.0.2 → 7.0.3

Eine technische Analyse

Kopfdaten und Grenzen

Release
7.0.2 → 7.0.3
Commits
7
Geänderte Dateien
21
Analyse
11.08.2026
Schwerpunkt
Sicherheitsfix und Datumskorrektur

Nicht untersucht

Verglichen wurden die Tags 7.0.2+260617 (Commit vom 2026-06-16) und 7.0.3+260618 (Commit vom 2026-06-17) mit git log --oneline 7.0.2+260617..7.0.3+260618 und git diff --stat 7.0.2+260617..7.0.3+260618; beide Tags waren im Repository vorhanden. Nicht inhaltlich ausgewertet wurden die vier binären Katalogdateien locale/de/de.mo, locale/de-informal/de-informal.mo, locale/it/it.mo und locale/it-informal/it-informal.mo sowie die Änderungen an locale/_template/limesurvey.pot; die beiden Übersetzungs-Commits sind damit nur als vorhanden vermerkt, und ob dabei Texte entfallen sind, bleibt offen. Ebenfalls nicht herangezogen wurden Laufzeitumgebung, Testsuite und die externen Vorgangsnummern AT-2090, AT-2084 und #20565, weshalb Aussagen über Ausnutzbarkeit in einer konkreten Installation und über den Umfang der zugehörigen Vorgänge offenbleiben. Indirekte Effekte über transitive Drittabhängigkeiten sind durch reine Diff-Analyse nicht vollständig erfassbar. Die Kurzliste lässt keine Einträge aus.

Executive Summary

7.0.3 ist ein kleines Wartungsrelease mit zwei inhaltlichen Änderungen: einem ausdrücklich als Sicherheitsfix markierten Commit in der Statistikauswertung und einer Neufassung der Datumsverarbeitung beim Speichern der allgemeinen Umfrageeinstellungen. Der Rest sind Übersetzungen, eine Textkorrektur an den Aria-Labels der Blätterleiste und eine neue Tabellenkomponente im Quellbaum des React-Editors. Am ehesten unbemerkt kaputtgeht die Datumsverarbeitung: Die neue Parserfunktion gibt bei nicht eindeutig deutbarer Eingabe null zurück, und weil die Validierungsregel leere Werte zulässt, wird daraus ein Start- oder Ablaufdatum, das schlicht nicht mehr gesetzt ist. Eine Datenbankmigration enthält das Release nicht.

  1. SQL-Injection in der Statistikauswertung geschlossen
  2. Datumsverarbeitung beim Speichern der Umfrageeinstellungen neu gefasst

Upgrade-Empfehlung

✅ Sofort installieren

Das Release schließt eine als Sicherheitsproblem gekennzeichnete Lücke in der Statistikauswertung und erfordert dafür keine Anpassung an Bestandssystemen. Der Diff enthält weder eine Migration noch eine neue Konfigurationsdatei, das Update ist damit rein dateibasiert. Prüfe nach dem Update die Start- und Ablaufdaten laufender Umfragen.

Lesepfad

ZielgruppeRelevante Kennungen und Kapitel
AdministratorenA1, A2, Weitere relevante Änderungen, Empfehlung
Plugin-EntwicklerA2, Empfehlung
Theme-Entwicklerkeine Kennung, Weitere relevante Änderungen, Empfehlung
IntegratorenA1, A2, Empfehlung
API-NutzerA1, Empfehlung

Die wichtigsten Änderungen

A1: SQL-Injection in der Statistikauswertung geschlossen

Sicherheitsrelevanz
Hoch
Handlungsdruck
Niedrig
Bruchverhalten
Kein Bruch
Betroffen
Administratoren, Integratoren, API-Nutzer

Hintergrund: In buildOutputList() der Klasse statistics_helper wird für die numerischen Fragetypen die SGQA-Kennung des auszuwertenden Feldes verarbeitet. Die Liste dieser Kennungen stammt im Administrationsbereich aus dem Anfrageparameter summary, den der Statistik-Controller über returnGlobal('summary') einliest und an einem Pluszeichen zerlegt; der Einstieg liegt hinter der Prüfung hasSurveyPermission($surveyid, 'statistics', 'read'). Dieselbe Kennung dient anschließend, um ein führendes Q gekürzt, als Spaltenname in einem SELECT über die Antworttabelle der Umfrage. Der Spaltenname geht dabei durch quoteColumnName() von Yii, das den Namen lediglich in die datenbankspezifischen Anführungszeichen einfasst. Vor der Änderung wurde die Kennung ohne Prüfung als Schlüssel in die Feldabbildung eingesetzt; ein dort nicht vorhandener Wert lief also weiter bis in die Abfrage. Die Änderung prüft den Schlüssel zuerst gegen die Feldabbildung und bricht die Auswertung dieses Feldes andernfalls ab.

Konsequenz: In die Abfrage gelangen nur noch Kennungen, die die Feldabbildung der Umfrage tatsächlich enthält. Für reguläre Statistikaufrufe ändert sich nichts, da die von der Oberfläche erzeugten Kennungen aus derselben Feldabbildung stammen. Die Prüfung sitzt in statistics_helper; die öffentliche Statistikseite verwendet mit userstatistics_helper eine andere Klasse, die der Diff nicht berührt — dort baut der Controller StatisticsUserController die Feldliste über createSGQA() selbst aus den Fragen der Umfrage auf, statt sie aus der Anfrage zu übernehmen. Für eine unbekannte Kennung liefert die Funktion jetzt ein leeres Array zurück, und die aufrufende Schleife liest aus dem Rückgabewert den Schlüssel statisticsoutput ohne vorherige Prüfung; je nach Fehlerberichterstattung kann dort also eine PHP-Warnung erscheinen, wo vorher ein Datenbankfehler stand.

Vorher / Nachher:

// Vorher (application/helpers/admin/statistics_helper.php)
$fielddata = $fieldmap[($fld[1] === 'Q') ? substr($fld, 1) : $fld];
// Nachher
$fieldkey = ($fld[1] === 'Q') ? substr($fld, 1) : $fld;
if (!array_key_exists($fieldkey, $fieldmap)) {
    return [];
}
$fielddata = $fieldmap[$fieldkey];

Nach dem Update testen: Rufe für eine Umfrage mit numerischen Fragen und vorhandenen Antworten die Statistik im Administrationsbereich auf, wähle alle Felder aus und vergleiche die HTML-, PDF- und XLS-Ausgabe mit dem Stand vor dem Update. Sende an dieselbe Aktion einen summary-Parameter mit einer SGQA-Kennung, die es in der Umfrage nicht gibt, und prüfe, dass keine Datenbankfehlermeldung erscheint. Rufe über RemoteControl export_statistics für dieselbe Umfrage auf und vergleiche das Ergebnisdokument.

Betroffene Dateien: application/helpers/admin/statistics_helper.php

Relevante Commits: e152894267

CVE / Advisory: Eine CVE-Kennung ist im Repository nicht auffindbar. Der Commit ist in der Betreffzeile ausdrücklich mit [security] markiert und nennt die interne Vorgangsnummer AT-2090; dieselbe Angabe steht im Änderungsprotokoll unter docs/release_notes.txt.

A2: Datumsverarbeitung beim Speichern der Umfrageeinstellungen neu gefasst

Sicherheitsrelevanz
Keine
Handlungsdruck
Mittel
Bruchverhalten
Stiller Fehler
Betroffen
Administratoren, Plugin-Entwickler, Integratoren

Hintergrund: Start- und Ablaufdatum einer Umfrage werden im klassischen Speicherpfad zweifach angefasst: Der Administrations-Controller Database schob die Eingabewerte durch getUTCOfDate(), und der Dienst GeneralSettings wandelte dieselben Werte anschließend über die Bibliothek Date_Time_Converter aus dem Anzeigeformat des Benutzers in das Datenbankformat um. Die Änderung entfernt die Umwandlung im Controller ersatzlos und ersetzt die Bibliotheksnutzung im Dienst durch eine neue Funktion convertFromGlobalSettingFormat() in common_helper.php, die das Gegenstück zum bereits vorhandenen convertToGlobalSettingFormat() bildet. Die neue Funktion parst gegen das im Sitzungskontext hinterlegte Datumsformat, verwirft Werte, die der Parser nur unter Warnungen zurechtbiegt, und fällt für Werte, die dem Anzeigeformat gar nicht entsprechen, auf den regulären DateTime-Konstruktor zurück. Die Validierungsregeln des Modells Survey nehmen zusätzlich das Format mit vierstelliger Jahres- und zweistelliger Monats-, Tages-, Stunden-, Minuten- und Sekundenangabe als erste Alternative auf.

Konsequenz: Start- und Ablaufdatum werden beim Speichern nur noch einmal umgerechnet und landen damit in der Zeitzone, die der Benutzer sieht. Die Änderung greift ausschließlich im klassischen Speicherpfad; im REST-Modus übernimmt laut dem Kommentar an der Aufrufstelle weiterhin der API-Transformer die Formatumwandlung, dort ändert sich nichts. Bemerkenswert ist der Fehlerfall: Kann die neue Funktion einen Wert nicht eindeutig deuten, gibt sie null zurück, getUTCOfDate() reicht null unverändert weiter, und weil die Validierungsregel leere Werte ausdrücklich zulässt, wird das Feld ohne Fehlermeldung geleert. Eine Umfrage, deren Ablaufdatum auf diese Weise verschwindet, läuft weiter, statt zu schließen. Bereits gespeicherte, falsch umgerechnete Werte korrigiert die Änderung nicht; sie wirkt erst beim nächsten Speichern.

Vorher / Nachher:

// Vorher (application/models/services/SurveyAggregateService/GeneralSettings.php)
private function formatDateTimeInput($inputDateTimeString)
{
    $this->yiiApp->loadHelper('surveytranslator');
    $this->yiiApp->loadLibrary('Date_Time_Converter');
    ...
    $dateTimeObj = new Date_Time_Converter(
        $inputDateTimeString,
        $formatData['phpdate'] . ' H:i'
    );
    return $dateTimeObj->convert('Y-m-d H:i:s');
}
// Nachher
private function formatDateTimeInput($inputDateTimeString)
{
    return getUTCOfDate(convertFromGlobalSettingFormat($inputDateTimeString, true));
}
// Neu (application/helpers/common_helper.php)
function convertFromGlobalSettingFormat(?string $sDate, bool $withTime = false): ?string
{
    ...
    $oDate = DateTime::createFromFormat('!' . $fromFormat, $sDate);
    ...
        $errors = DateTime::getLastErrors();
        if ($errors !== false && (($errors['warning_count'] ?? 0) > 0 || ($errors['error_count'] ?? 0) > 0)) {
            return null;
        }
    ...
    return $oDate->format('Y-m-d H:i:s');
// Vorher (application/models/Survey.php)
array('expires', 'date','format' => ['yyyy-M-d H:m:s.???','yyyy-M-d H:m:s','yyyy-M-d H:m'],'allowEmpty' => true),
// Nachher
array('expires', 'date','format' => ['yyyy-MM-dd HH:mm:ss','yyyy-M-d H:m:s.???','yyyy-M-d H:m:s','yyyy-M-d H:m'],'allowEmpty' => true),

Nach dem Update testen: Öffne die allgemeinen Einstellungen einer Umfrage mit gesetztem Start- und Ablaufdatum, speichere ohne inhaltliche Änderung und vergleiche die Spalten startdate und expires der Tabelle surveys vor und nach dem Speichern. Wiederhole das mit einem Benutzerkonto, dessen Datumsformat und Anzeige-Zeitzone von den Voreinstellungen abweichen. Trage anschließend ein Datum ein, das dem eingestellten Anzeigeformat nicht entspricht, und prüfe, ob das Feld danach leer ist, statt eine Fehlermeldung auszulösen.

Betroffene Dateien: application/helpers/common_helper.php, application/models/services/SurveyAggregateService/GeneralSettings.php, application/controllers/admin/Database.php, application/models/Survey.php

Relevante Commits: c72daef6dd

Weitere relevante Änderungen

Aria-Labels der Blätterleiste vereinheitlicht
Themes und Rendering · Kein Bruch · Administratoren, Theme-Entwickler
Die Blätterleiste im Administrationsbereich meldet für Vor- und Zurück-Schaltflächen nur noch ein Ziel-Label, unabhängig davon, ob die Schaltfläche als ausgewählt gilt. (2e379577ae)

Tabellenkomponente für den React-Editor ergänzt
Themes und Rendering · Kein Bruch · Administratoren
Der Editor-Quellbaum enthält eine sortier- und auswählbare Tabellenkomponente mit eigenem SCSS-Bündel, die erst nach einem Neubau der Editor-Assets in der Oberfläche erscheint. (2c68ca2068)

Zuordnung nach Bereich

BereichVollständig beschriebenWeitere Einträge
SicherheitA1
Datenbankkeine
RemoteControl APIA1
Survey RuntimeA2
Themes und Renderingkeineja
Plugin-Kompatibilitätkeine
Performancekeine

Nicht betroffene Bereiche

  • Weder application/helpers/update/updatedb_helper.php noch ein Eintrag unter application/helpers/update/updates erscheint im Diff, und die interne Datenbank-Versionsnummer in application/config/version.php steht vor und nach dem Update auf demselben Wert. Struktur-, Spalten-, Index- und Constraint-Änderungen sind daraus nicht ableitbar.
  • composer.json, composer.lock und package.json erscheinen nicht im Diff; der Satz der deklarierten Abhängigkeiten und die deklarierten Mindestanforderungen bleiben damit auf dem Stand von 7.0.2.
  • application/helpers/remotecontrol/remotecontrol_handle.php erscheint nicht im Diff; die Methodenliste der JSON-RPC-Schnittstelle und die Signaturen ihrer Methoden sind unverändert. Die Auswirkung von A1 auf diesen Bereich entsteht ausschließlich über die aufgerufene Hilfsklasse.
  • Unter themes/survey sowie in application/core/LSETwigViewRenderer.php und application/core/LS_Twig_Extension.php zeigt der Diff keine Änderungen; die ausgelieferten Umfrage-Themes und der Satz der Twig-Erweiterungsfunktionen bleiben damit auf dem Stand von 7.0.2.

Beleg für die unveränderte Datenbank-Versionsnummer:

// Vorher (application/config/version.php)
$config['versionnumber'] = '7.0.2';
$config['dbversionnumber'] = 708;
...
$config['assetsversionnumber'] = '30490';
// Nachher
$config['versionnumber'] = '7.0.3';
$config['dbversionnumber'] = 708;
...
$config['assetsversionnumber'] = '30491';

Empfehlung

Administratoren

Vor dem Update: Sichere Datenbank und Dateibaum wie üblich. Notiere Start- und Ablaufdatum der aktiv laufenden Umfragen, um sie nach dem Update vergleichen zu können (A2). Halte eine Statistikausgabe einer Umfrage mit numerischen Fragen als Referenz bereit (A1).

Unmittelbar nach dem Update: Rufe die Statistik derselben Umfrage auf und vergleiche sie mit der Referenz (A1). Speichere die allgemeinen Einstellungen einer laufenden Umfrage und prüfe die gespeicherten Datumswerte in der Datenbank (A2). Baust du die Installation selbst aus den Paketquellen, baue die Editor-Assets neu, damit der geänderte SCSS-Einstieg und die neue Komponente enthalten sind (siehe Weitere relevante Änderungen).

Rollback: Der Diff enthält keine Migration, die interne Datenbank-Versionsnummer bleibt auf demselben Wert, und eine neue Konfigurationsdatei wird nicht angelegt; ein Zurückwechseln der Programmdateien auf 7.0.2 ist daher ohne Datenbank-Rollback möglich. Ob Datumswerte, die zwischenzeitlich unter 7.0.3 gespeichert wurden, von 7.0.2 identisch interpretiert werden, ist aus dem Diff nicht bestimmbar — prüfe das vor einem Rollback in einer Testumgebung mit einer Kopie der Produktivdaten.

Plugin-Entwickler

Prüfe eigenen Code, der Start- oder Ablaufdaten von Umfragen schreibt: Der Administrations-Controller rechnet diese Werte nicht mehr in UTC um, die Umrechnung liegt jetzt vollständig im Dienst für die allgemeinen Einstellungen (A2). Für eigene Umrechnungen steht mit convertFromGlobalSettingFormat() eine neue globale Funktion in common_helper.php bereit, die das Gegenstück zu convertToGlobalSettingFormat() bildet; beachte, dass sie bei nicht deutbarer Eingabe null liefert und dieser Wert unverändert bis in die Speicherung durchgereicht wird.

Theme-Entwickler

Keine der vollständig beschriebenen Änderungen betrifft diese Gruppe. Enthalten eigene Anpassungen oder automatisierte Oberflächentests des Administrationsbereichs Annahmen über die Aria-Labels der Blätterleiste, gleiche sie mit dem geänderten Text ab (siehe Weitere relevante Änderungen).

Integratoren

Automatisierte Aufrufe der Statistikausgabe, die Feldkennungen selbst zusammensetzen, liefern für unbekannte Kennungen jetzt einen leeren Abschnitt statt eines Fehlers; prüfe, ob deine Auswertung diesen Fall von einem regulären leeren Ergebnis unterscheiden muss (A1). Schreibt deine Integration Umfrageeinstellungen über den klassischen Administrationspfad, sende Start- und Ablaufdatum in dem Format, das für das verwendete Benutzerkonto eingestellt ist, und prüfe nach dem Schreiben, ob der Wert tatsächlich gesetzt wurde (A2).

API-Nutzer

Der RemoteControl-Aufruf export_statistics verwendet dieselbe Hilfsklasse wie der Administrationsbereich und ist damit von der geänderten Feldprüfung erfasst (A1). Vergleiche für eine Umfrage mit numerischen Fragen das erzeugte Dokument vor und nach dem Update; die Signaturen der Schnittstelle selbst bleiben unverändert.