LimeSurvey 7.0.7 → 7.0.8

Eine technische Analyse

Kopfdaten und Grenzen

Release
7.0.7 → 7.0.8
Commits
29
Geänderte Dateien
136
Analyse
11.08.2026
Schwerpunkt
Fehlerbehebungen und Editorarbeiten

Nicht untersucht

Verglichen wurden die Tags 7.0.7+260729 und 7.0.8+260806 mit git log --oneline 7.0.7+260729..7.0.8+260806 und git diff --stat 7.0.7+260729..7.0.8+260806; beide Tags sind im Repository vorhanden und liegen auf dem Zweig master. Nicht ausgewertet wurden die Übersetzungsdateien unterhalb von locale/, die kompilierten Bundles unterhalb von editor/build/ sowie die JavaScript-Quellkarten; Aussagen über Zeichenketten in einzelnen Sprachen und über das exakte Laufzeitverhalten der ausgelieferten Bundles bleiben deshalb offen. Die Testdateien unterhalb von tests/ wurden nur daraufhin gesichtet, welche Produktionsänderung sie begleiten, nicht auf ihre Abdeckung hin. Indirekte Effekte über transitive Drittabhängigkeiten sind durch reine Diff-Analyse nicht vollständig erfassbar, weil der Diff nur die im Repository eingecheckten Paketstände zeigt und nicht das Verhalten der Pakete untereinander. Aus dem Kapitel „Weitere relevante Änderungen" ist ein Eintrag geringerer Relevanz weggelassen, weil er sich keinem der sieben vorgegebenen Bereiche zuordnen ließ: die geänderte Fehlermeldung der Anmeldung bei abgelaufenem Benutzerkonto.

Executive Summary

Dieses Release ist ein reines Wartungsrelease ohne Datenbankmigration: 29 Commits, überwiegend Fehlerbehebungen, dazu ein als Sicherheitsfix gekennzeichneter Commit und eine große Gruppe von Arbeiten am neuen Fragen-Editor. Die eine Sache, die am ehesten unbemerkt kaputtgeht, ist die Zeitstempel-Behandlung anonymisierter Umfragen: Ab dieser Version schreibt LimeSurvey in anonymisierten Umfragen ein festes Platzhalterdatum in die Antworttabelle, statt den tatsächlichen Zeitpunkt zu speichern. Wer auf datestamp, startdate oder submitdate auswertet, bekommt weiterhin plausible Werte geliefert, nur eben falsche. Ebenfalls still wirkt die Neufassung der öffentlichen URL-Erzeugung: Installationen mit gesetzter öffentlicher Basis-URL erhalten in Mails und Platzhaltern jetzt andere Adressen als zuvor. Beides fällt ohne gezielte Prüfung nicht auf.

  1. Anonymisierte Umfragen speichern ein Platzhalterdatum
  2. Erzeugung öffentlicher URLs bei abweichender Basis-URL
  3. XSS im Formular für Dummy-Teilnehmer
  4. Rückgabewerte der Theme-Kompatibilitätsprüfung
  5. Reihenfolge der Ersetzungen im Mailer
  6. Pflichtprüfung und Auswahlübernahme bei Ranking-Fragen
  7. Schriften im neuen Editor werden lokal ausgeliefert
  8. Überarbeitungen im neuen Fragen-Editor

Upgrade-Empfehlung

🧪 Vorher testen

Das Release enthält keine Datenbankmigration und erzwingt keine Anpassung, verändert aber an zwei Stellen still die erzeugten Daten beziehungsweise Adressen. Wer anonymisierte Umfragen auswertet oder eine abweichende öffentliche Basis-URL konfiguriert hat, sollte diese beiden Punkte in einer Testumgebung prüfen, bevor produktiv aktualisiert wird. Für alle übrigen Installationen ist das Update unkritisch.

Lesepfad

ZielgruppeRelevante Kennungen und Kapitel
AdministratorenA1, A2, A3, A4, A5, A6, A7, A8, Weitere relevante Änderungen, Empfehlung
Plugin-EntwicklerA2, A4, A5, A8, Weitere relevante Änderungen, Empfehlung
Theme-EntwicklerA4, A6, A7, A8, Weitere relevante Änderungen, Empfehlung
IntegratorenA1, A2, A5, A6, Weitere relevante Änderungen, Empfehlung
API-NutzerA1, A5, Empfehlung

Die wichtigsten Änderungen

A1: Anonymisierte Umfragen speichern ein Platzhalterdatum

Sicherheitsrelevanz
Niedrig
Handlungsdruck
Mittel
Bruchverhalten
Stiller Fehler
Betroffen
Administratoren, Integratoren, API-Nutzer

Hintergrund: Bisher galt die Anonymisierung einer Umfrage nur für die Zuordnung zwischen Teilnehmer und Antwort. Die Zeitstempelspalten der Antworttabelle wurden weiterhin mit dem tatsächlichen Zeitpunkt gefüllt, sofern die Zeitstempelung aktiviert war. Damit ließ sich über die Uhrzeit einer Antwort in vielen Fällen auf die Person zurückschließen, insbesondere bei kleinen Teilnehmerkreisen. Die Änderung führt eine private Hilfsmethode ein, die ein festes Datum zurückliefert, und ruft sie an drei Stellen auf: beim erstmaligen Anlegen des Datensatzes für datestamp und startdate, beim Aktualisieren für datestamp sowie beim Abschluss für submitdate. Der bisher schon vorhandene feste Wert für submitdate bei abgeschalteter Zeitstempelung wird auf dieselbe Methode umgestellt, sodass alle vier Schreibpfade denselben Wert verwenden.

Konsequenz: In anonymisierten Umfragen mit aktivierter Zeitstempelung enthalten die Spalten datestamp, startdate und submitdate ab dieser Version nicht mehr den tatsächlichen Zeitpunkt, sondern einen konstanten Platzhalterwert. Auswertungen, Exporte und über die Schnittstelle abgerufene Antwortdatensätze liefern weiterhin ein syntaktisch gültiges Datum, sodass nachgelagerte Systeme keinen Fehler melden, sondern schlicht falsche Werte verarbeiten. Betroffen sind Zeitreihen, Rücklaufkurven, Bearbeitungsdauern und jede Logik, die Antworten nach Zeitpunkt sortiert oder filtert. Die Änderung greift ausschließlich für Umfragen, in denen die Anonymisierung eingeschaltet ist; nicht anonymisierte Umfragen behalten das bisherige Verhalten. Bereits vorhandene Antwortdatensätze werden nicht verändert, es findet keine nachträgliche Umschreibung statt. Damit entstehen in laufenden anonymisierten Umfragen gemischte Datenbestände: Antworten vor dem Update tragen echte Zeitstempel, Antworten danach den Platzhalter. Ob und wie sich das Verhalten pro Umfrage abschalten lässt, ist im Diff nicht erkennbar; eine entsprechende Konfigurationsoption ist dort nicht sichtbar.

Vorher / Nachher:

// Vorher (application/helpers/expressions/em_manager_helper.php)
if ($this->surveyOptions['datestamp']) {
    $submitdate = gmdate("Y-m-d H:i:s");
} else {
    $submitdate = date("Y-m-d H:i:s", mktime(0, 0, 0, 1, 1, 1980));
}
// Nachher
if ($this->surveyOptions['datestamp'] && !$this->surveyOptions['anonymized']) {
    $submitdate = gmdate("Y-m-d H:i:s");
} else {
    $submitdate = $this->anonymizeDate();
}
// Neu (application/helpers/expressions/em_manager_helper.php)
if ($this->surveyOptions['datestamp'] == true) {
    $sdata['datestamp'] = $_SESSION[$this->sessid]['datestamp'];
    $sdata['startdate'] = $_SESSION[$this->sessid]['datestamp'];
    if($this->surveyOptions['anonymized']){
        //all dates should be anonymized
        $sdata['datestamp'] = $this->anonymizeDate();
        $sdata['startdate'] = $this->anonymizeDate();
    }
}

Nach dem Update testen: Eine anonymisierte Testumfrage mit aktivierter Zeitstempelung ausfüllen und anschließend in der Antworttabelle prüfen, welche Werte in datestamp, startdate und submitdate stehen. Denselben Datensatz zusätzlich über den Antwortexport und über die verwendete Auswertungsstrecke abrufen, um festzustellen, ob nachgelagerte Berichte den Platzhalterwert stillschweigend übernehmen.

Betroffene Dateien: application/helpers/expressions/em_manager_helper.php, application/models/SurveyDynamic.php

Relevante Commits: 9bd9bbab1c

A2: Erzeugung öffentlicher URLs bei abweichender Basis-URL

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

Hintergrund: Die Methode createPublicUrl erzeugt die Adressen, die in Einladungs- und Benachrichtigungsmails sowie in URL-Platzhaltern erscheinen. Sie vergleicht die konfigurierte öffentliche Basis-URL mit der tatsächlich ermittelten und schneidet im Abweichungsfall den ermittelten Anteil vom erzeugten absoluten Link ab, um ihn durch den konfigurierten zu ersetzen. Dieses Abschneiden per Zeichenkettenvergleich schlug fehl, sobald hostInfo oder baseUrl in der Konfiguration abweichend gesetzt waren: Der von Yii erzeugte absolute Link begann dann nicht mehr mit der ermittelten Basis-URL, der Vergleich griff nicht, und der konfigurierte Präfix wurde vor eine bereits vollständige Adresse gesetzt. Die Neufassung dreht das Vorgehen um. Sie sichert den aktuellen Zustand von URL-Manager und Anfrageobjekt, setzt hostInfo auf eine leere Zeichenkette und die Basis-URL abhängig von showScriptName auf /index.php oder auf leer, erzeugt in diesem neutralisierten Zustand den Link und stellt anschließend beide Werte wieder her.

Konsequenz: Installationen, in denen die öffentliche Basis-URL von der intern ermittelten abweicht, erhalten in Mails und Platzhaltern ab dieser Version andere Adressen als zuvor. Wo bisher fehlerhaft zusammengesetzte Links entstanden, entstehen jetzt korrekte; wo bisher zufällig korrekte Links entstanden, kann sich die Form der Adresse dennoch ändern, weil der Erzeugungsweg ein anderer ist. Die Änderung greift ausschließlich dann, wenn die konfigurierte öffentliche Basis-URL und die ermittelte Basis-URL sich unterscheiden. Ist keine abweichende öffentliche Basis-URL konfiguriert, läuft der bisherige Zweig unverändert weiter und es ändert sich nichts. Eigener Code, der createPublicUrl aufruft, sieht das neue Verhalten ohne Anpassung. Wer sich auf die exakte Zeichengestalt der erzeugten Adressen verlässt, etwa beim Abgleich von Rücksprungadressen oder in Filterregeln eines vorgelagerten Proxys, muss diese Regeln prüfen. Kritisch ist dabei, dass fehlerhafte Adressen erst auffallen, wenn ein Empfänger auf den Link klickt, also verzögert und außerhalb des eigenen Systems.

Vorher / Nachher:

// Vorher (application/core/Traits/LSApplicationTrait.php)
$sPublicUrl = $this->getPublicBaseUrl(true);
$sActualBaseUrl = $this->getBaseUrl(true);
if ($sPublicUrl !== $sActualBaseUrl) {
    $url = $this->createAbsoluteUrl($route, $params, $schema, $ampersand);
    if (substr((string)$url, 0, strlen((string)$sActualBaseUrl)) == $sActualBaseUrl) {
        $url = substr((string)$url, strlen((string)$sActualBaseUrl));
    }
    return trim((string)$sPublicUrl, "/") . $url;
// Nachher
if ($this->getUrlManager()->showScriptName) {
    $this->getUrlManager()->setBaseUrl("/index.php");
} else {
    $this->getUrlManager()->setBaseUrl("");
}
$this->getRequest()->setHostInfo("");
$url = $this->createAbsoluteUrl($route, $params, $schema, $ampersand);
$this->getUrlManager()->setBaseUrl($sActualBaseUrl);
$this->getRequest()->setHostInfo($sActualhostInfo);

Nach dem Update testen: In einer Installation mit abweichend konfigurierter öffentlicher Basis-URL eine Einladungsmail an eine Testadresse versenden und die enthaltene Umfrage-Adresse zeichenweise mit der vor dem Update erzeugten vergleichen. Zusätzlich einen Link aus einer Administrator-Benachrichtigung im Browser aufrufen und prüfen, ob er ohne Umleitung auf der erwarteten Seite landet.

Betroffene Dateien: application/core/Traits/LSApplicationTrait.php, tests/unit/LSYiiApplicationTest.php, tests/TestHelper.php

Relevante Commits: 3b6cf7dfd9

A3: XSS im Formular für Dummy-Teilnehmer

Sicherheitsrelevanz
Mittel
Handlungsdruck
Niedrig
Bruchverhalten
Kein Bruch
Betroffen
Administratoren

Hintergrund: Das Formular zum Anlegen von Dummy-Teilnehmern gab die abgeschickten Werte für Vorname, Nachname, E-Mail-Adresse, Anzahl, Zugangscodelänge und verbleibende Verwendungen unmaskiert in die value-Attribute der Eingabefelder zurück. Bei einer Rückkehr ins Formular, etwa nach einem Validierungsfehler in den Teilnehmerattributen, gelangte der eingesandte Inhalt damit unverändert in die ausgelieferte Seite. Die Behebung maskiert die Textfelder mit CHtml::encode und wandelt die numerischen Felder mit intval um. Derselbe Commit ordnet den Kontrollfluss der Aktion neu: Der Zweig, der die Dummy-Datensätze erzeugt, läuft jetzt nur noch bei fehlerfreier Attributvalidierung, das Formular wird auf einem gemeinsamen Weg am Ende der Methode aufgebaut, und die Standardwerte für Sprache, Anzahl und Zugangscodelänge werden bereits beim Auslesen der Anfrage gesetzt statt erst im Fehlerfall.

Konsequenz: Der Einschleusungsweg über das Formular ist geschlossen. Ausnutzbar war er nur für Konten, die das Formular überhaupt aufrufen dürfen, also mit Teilnehmerverwaltungsrecht auf der betroffenen Umfrage, und er erforderte, dass das Opfer das präparierte Formular absendet; die Einstufung als Mittel folgt daraus. Für den laufenden Betrieb ändert sich das sichtbare Verhalten an zwei Stellen: Die Felder für Vorname, Nachname und E-Mail-Adresse tragen jetzt einen Hinweistext, der den Zählerplatzhalter erklärt, und bei fehlerhaften Teilnehmerattributen bleibt der Anwender im Formular, ohne dass zuvor Datensätze angelegt wurden. Zuvor wurden die Datensätze auch dann erzeugt, wenn die Attributvalidierung anschlug. Anpassungen an eigener Konfiguration sind nicht erforderlich. Im Repository ist zu diesem Commit keine CVE-Kennung und kein Advisory-Link auffindbar; die Sicherheitsmarkierung ergibt sich aus dem Präfix [security] in der Commit-Nachricht und der Ausgabennummer.

Vorher / Nachher:

// Vorher (application/views/admin/token/dummytokenform.php)
<input class='form-control' type='number' min='1' size='20' id='amount' name='amount' value="<?php echo $amount; ?>" />
...
<input class='form-control' type='text' size='30' id='firstname' name='firstname' value="<?php echo $firstname; ?>" />
...
<input class='form-control' type='text' size='20' id='usesleft' name='usesleft' value="<?php echo $usesleft; ?>" />
// Nachher
<input class='form-control' type='number' min='1' size='20' id='amount' name='amount' value="<?php echo intval($amount); ?>" />
...
<input class='form-control' type='text' size='30' id='firstname' name='firstname' aria-describedby='firstname-help' value="<?= CHtml::encode($firstname); ?>" />
...
<input class='form-control' type='text' size='20' id='usesleft' name='usesleft' value="<?= CHtml::encode($usesleft); ?>" />

Nach dem Update testen: Im Formular für Dummy-Teilnehmer in das Feld für den Vornamen eine Zeichenkette mit spitzen Klammern und Anführungszeichen eintragen, ein ungültiges Teilnehmerattribut mitschicken und im zurückgelieferten Quelltext prüfen, dass der Wert maskiert im value-Attribut steht. Anschließend in der Teilnehmerliste kontrollieren, dass bei diesem Fehlversuch keine Datensätze angelegt wurden.

Betroffene Dateien: application/views/admin/token/dummytokenform.php, application/controllers/admin/Tokens.php

Relevante Commits: fbf58c99cb

CVE / Advisory: Keine CVE-Kennung und kein Advisory-Link im Repository auffindbar. Auffindbar sind die Ausgabennummer 20575 und die ausdrückliche Markierung [security] in der Commit-Nachricht.

A4: Rückgabewerte der Theme-Kompatibilitätsprüfung

Sicherheitsrelevanz
Keine
Handlungsdruck
Mittel
Bruchverhalten
Fehler zur Laufzeit
Betroffen
Administratoren, Theme-Entwickler, Plugin-Entwickler

Hintergrund: Die Prüfung eines Themes auf Verträglichkeit mit der laufenden LimeSurvey-Version deinstallierte ein unverträgliches Theme und meldete anschließend in jedem Fall Erfolg. Die Deinstallation selbst konnte jedoch scheitern, etwa wegen fehlender Berechtigung oder weil kein Datensatz zum Namen existiert. In diesem Fall lief die Verarbeitung mit einem Theme weiter, das weder verträglich noch entfernt war, und die Aktualisierung der Installation blieb hängen. Der Commit ändert drei Signaturen und Rückgabewerte. Die Deinstallation eines einzelnen Themes unterscheidet jetzt zwischen der Zahl entfernter Theme-Konfigurationen, dem Wert true für ein entferntes Theme ohne Konfigurationen und false für einen Fehlschlag. Die rekursive Deinstallation abgeleiteter Themes gibt statt void einen Wahrheitswert zurück und bricht beim ersten Fehlschlag ab. Die Prüfmethode gibt nicht mehr unbedingt true zurück, sondern den in einen Wahrheitswert gewandelten Verträglichkeitsstatus.

Konsequenz: Für Administratoren löst sich damit eine Blockade beim Aktualisieren: Ein unverträgliches Theme, das sich nicht entfernen lässt, führt jetzt zu einer verständlichen Meldung mit dem Namen des Seitenadministrators statt zu einem stillen Weiterlaufen. Für Theme- und Plugin-Entwickler ist die Änderung eine Signaturänderung im ausgelieferten Code. Wer die rekursive Deinstallation aus eigenem Code aufruft, bekommt einen Rückgabewert, wo zuvor keiner deklariert war; wer die Methode in einer eigenen Klasse überschreibt, muss die Deklaration auf den Wahrheitswert-Rückgabetyp anpassen, sonst schlägt das Laden der Klasse zur Laufzeit fehl. Wer die Prüfmethode aufruft und ihren Rückgabewert bisher als konstant wahr behandelt hat, erhält jetzt bei unverträglichen Themes einen unwahren Wert und muss den Folgezweig prüfen. Ob es außerhalb des Kerns Aufrufer dieser Methoden gibt, ist aus dem Diff nicht bestimmbar.

Vorher / Nachher:

// Vorher (application/models/TemplateConfig.php)
public static function uninstallThemesRecursive($templateName): void
{
    ...
            self::uninstallThemesRecursive($extendedTemplate->name);
    ...
    self::uninstall($templateName);
}
// Nachher
public static function uninstallThemesRecursive($templateName): bool
{
    ...
            if (!self::uninstallThemesRecursive($extendedTemplate->name)) {
                return false;
            }
    ...
    return boolval(self::uninstall($templateName));
}
// Vorher (application/models/TemplateConfig.php)
// all checks succeeded, continue loading the theme
return true;
// Nachher
// all checks succeeded, continue loading the theme if it compatible
return boolval($isCompatible);

Nach dem Update testen: Ein Theme mit einer bewusst unpassenden API-Version in der Manifestdatei installieren, anschließend die Theme-Übersicht aufrufen und prüfen, dass eine Meldung erscheint und die Oberfläche bedienbar bleibt. Danach mit einem Konto ohne Recht zum Entfernen von Themes denselben Aufruf wiederholen und kontrollieren, dass die zweite Meldung mit dem Hinweis auf den Seitenadministrator erscheint.

Betroffene Dateien: application/models/TemplateConfig.php, application/models/TemplateConfiguration.php

Relevante Commits: 9e6aa71beb

A5: Reihenfolge der Ersetzungen im Mailer

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

Hintergrund: Der Mailer setzt Platzhalter in drei Stufen zusammen: Kernersetzungen, Teilnehmerersetzungen und die von außen gesetzten Ersetzungen. Anschließend wandelt er die Platzhalter, deren Name auf URL endet, in anklickbare Verweise um. Die von außen gesetzten Ersetzungen wurden bisher erst nach diesem Umwandlungsschritt eingemischt und blieben deshalb unverlinkt. Der Commit zieht das Einmischen vor die Umwandlung und ergänzt die öffentliche Methode addAndReplaceReplacement, mit der sich Ersetzungen gezielt am Mailer-Objekt setzen lassen. Die Aufrufe in der Benachrichtigungsstrecke werden von der bisherigen Aktualisierung globaler Ersetzungsfelder auf diese Methode umgestellt, sodass die Antworttabelle je Empfänger am Mailer und nicht mehr am globalen Ausdrucksverwalter hinterlegt wird.

Konsequenz: Administratoren erhalten in Benachrichtigungsmails wieder anklickbare Verweise statt reiner Textadressen. Für Plugin-Entwickler steht mit addAndReplaceReplacement eine neue öffentliche Methode bereit, deren Werte bestehende Kern- und Teilnehmerersetzungen gleichen Namens überschreiben. Zugleich ändert sich still das Ergebnis für vorhandene Erweiterungen: Wer eigene Ersetzungen mit einem auf URL endenden Namen setzt, bekommt diese ab jetzt in einen Verweis eingebettet, wo zuvor der nackte Wert eingesetzt wurde. Bei reinen Textmails oder bei Werten, die bereits Markup enthalten, kann das zu doppelter Auszeichnung führen. Das fällt nicht als Fehler auf, sondern nur als veränderte Darstellung im Postfach des Empfängers. Die Umstellung in der Benachrichtigungsstrecke bedeutet außerdem, dass Erweiterungen, die die Antworttabelle bisher über den globalen Ausdrucksverwalter abgefangen oder verändert haben, an dieser Stelle nicht mehr greifen; ob es solche Erweiterungen gibt, ist aus dem Diff nicht bestimmbar.

Vorher / Nachher:

// Vorher (application/core/LimeMailer.php)
$aReplacements = array_merge($aReplacements, $aTokenReplacements);
foreach ($this->aUrlsPlaceholders as $urlPlaceholder) {
    if (!empty($aReplacements["{$urlPlaceholder}URL"])) {
        $url = $aReplacements["{$urlPlaceholder}URL"];
        ...
    }
}
$aReplacements = array_merge($aReplacements, $this->aReplacements);
// Nachher
$aReplacements = array_merge($aReplacements, $aTokenReplacements);
$aReplacements = array_merge($aReplacements, $this->aReplacements);
/* Replace URL placeholders for all replacements */
foreach ($this->aUrlsPlaceholders as $urlPlaceholder) {
    if (!empty($aReplacements["{$urlPlaceholder}URL"])) {
        $url = $aReplacements["{$urlPlaceholder}URL"];
        ...
    }
}
// Neu (application/core/LimeMailer.php)
public function addAndReplaceReplacement($replacements)
{
    $this->aReplacements = array_merge($this->aReplacements, $replacements);
}

Nach dem Update testen: Eine Umfrage mit aktivierter Administrator-Benachrichtigung abschließen und im Quelltext der eingegangenen Mail prüfen, dass die Adressplatzhalter als Verweis ausgezeichnet sind und die Antworttabelle vollständig enthalten ist. Anschließend, sofern Erweiterungen eigene Ersetzungen setzen, eine Mail mit einem auf URL endenden eigenen Platzhalter versenden und die Darstellung auf doppelte Auszeichnung prüfen.

Betroffene Dateien: application/core/LimeMailer.php, application/helpers/frontend_helper.php

Relevante Commits: e03a881a2d

A6: Pflichtprüfung und Auswahlübernahme bei Ranking-Fragen

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

Hintergrund: Ranking-Fragen mit Pflichtkennzeichen ließen sich nicht abschließen: Die Pflichtprüfung meldete eine Verletzung, obwohl alle Elemente eingeordnet waren. Der Commit setzt an drei Stellen an. Im Renderer der Ranking-Darstellung werden die erzeugten Feldnamen jetzt in der Eigenschaft inputnames des Renderers gesammelt statt in einer lokalen Variablen, die nach dem Verlassen der Methode verfiel. In der Pflichtprüfung des Ausdrucksverwalters wird von der Zahl der nicht beantworteten Unterfragen eine Eins abgezogen, bevor sie mit der zulässigen Höchstzahl verglichen wird. In den beiden Ranking-Skripten wird die Zuordnung zwischen Auswahlwert und Listenelement nicht mehr über eine aus dem Wert zusammengesetzte Kennung hergestellt, sondern über eine zuvor aus dem Dokument aufgebaute Zuordnungstabelle, die den Wert aus dem Attribut data-value liest.

Konsequenz: Ranking-Fragen mit Pflichtkennzeichen sind wieder ausfüllbar, und die Übernahme einer bestehenden Auswahl in die Sortierliste funktioniert auch für Antwortcodes, deren Zeichen in einer Selektorzeichenkette Sonderbedeutung haben. Die zusätzliche Zuordnungstabelle wird beim Umschalten aufgebaut; Elemente ohne data-value werden übersprungen. Eigene Ranking-Themes, die die Listenelemente ohne dieses Attribut ausgeben, verlieren damit die Auswahlübernahme, ohne dass ein Fehler erscheint. Offen bleibt die Wirkung des abgezogenen Werts in der Pflichtprüfung: Der Diff belegt, dass die Prüfung ab jetzt eine nicht eingeordnete Unterfrage mehr toleriert als zuvor, aber nicht, ob diese Toleranz in allen Konfigurationen genau die zuvor fehlende Registrierung der Feldnamen ausgleicht. Für Ranking-Fragen mit gesetzter Mindest- oder Höchstzahl an Antworten ist deshalb nicht bestimmbar, ob die Pflichtprüfung in jedem Fall gleich streng bleibt; das ist in einer Testumgebung zu prüfen.

Vorher / Nachher:

// Vorher (application/helpers/expressions/em_manager_helper.php)
if (count($unansweredSQs) > $maxUnrankedAnswers) {
    $qmandViolation = true; // TODO - what about 'other'?
}
// Nachher
if (count($unansweredSQs) - 1 > $maxUnrankedAnswers) {
    $qmandViolation = true; // TODO - what about 'other'?
}
// Vorher (application/core/QuestionTypes/RankingStyle/RenderRanking.php)
$inputnames[] = $myfname;
// Nachher
$this->inputnames[] = $myfname;

Nach dem Update testen: Eine Ranking-Frage mit Pflichtkennzeichen und ohne Mindest- oder Höchstzahl ausfüllen und prüfen, dass die Seite abgeschickt werden kann. Anschließend dieselbe Frage mit gesetzter Höchstzahl an Antworten testen und gezielt eine Unterfrage nicht einordnen, um festzustellen, ob die Pflichtmeldung wie erwartet erscheint. Zusätzlich eine Ranking-Frage mit einem Antwortcode prüfen, der Sonderzeichen enthält, und die Auswahl vom Auswahlfeld in die Sortierliste umschalten.

Betroffene Dateien: application/core/QuestionTypes/RankingStyle/RenderRanking.php, application/helpers/expressions/em_manager_helper.php, assets/packages/questions/ranking/scripts/ranking.js, themes/question/ranking_advanced/survey/questions/answer/ranking/assets/scripts/advanced_ranking.js

Relevante Commits: 7c78ce036d

A7: Schriften im neuen Editor werden lokal ausgeliefert

Sicherheitsrelevanz
Niedrig
Handlungsdruck
Niedrig
Bruchverhalten
Kein Bruch
Betroffen
Administratoren, Theme-Entwickler

Hintergrund: Die Stilvorlagen des neuen Fragen-Editors banden die verwendete Schriftfamilie über eine @import url(...)-Anweisung von einem Schriftdienst eines Drittanbieters ein. Jeder Aufruf des Editors erzeugte damit eine Anfrage an einen fremden Server, die die Adresse des aufrufenden Rechners und den Verweiser übermittelt. Der Commit entfernt beide Vorkommen dieser Anweisung und ersetzt sie durch den Import einer neuen Stilvorlagendatei, die sechzehn @font-face-Regeln mit lokalen Dateipfaden enthält. Die Schriftdateien selbst werden als Teil des Bundles mit ausgeliefert. Ergänzend wird die Bündelungskonfiguration so eingestellt, dass Adressen in url()-Angaben relativ zur erzeugten Stilvorlagendatei aufgelöst werden, damit die Pfade auch bei Installation in einem Unterverzeichnis stimmen.

Konsequenz: Der Editor lädt seine Schriften ab dieser Version aus der eigenen Installation. Damit entfällt der Abfluss von Verbindungsdaten an einen Drittanbieter beim Öffnen des Editors, was für Betreiber mit Auflagen zur Datenverarbeitung praktisch bedeutsam ist, und der Editor bleibt in Netzen ohne ausgehende Verbindung vollständig darstellbar. Die Einstufung der Sicherheitsrelevanz als Niedrig folgt daraus, dass Inhalte von einem fremden Server nicht mehr in die Verwaltungsoberfläche geladen werden; ein konkreter Angriffsweg ist im Diff nicht belegt. Die Änderung wirkt ausschließlich für den neuen Fragen-Editor. Ob andere Teile der Verwaltungsoberfläche oder ausgelieferte Umfragethemes weiterhin externe Schriften einbinden, ist aus diesem Commit nicht ableitbar. Administratoren, die ihre Installation selbst aus den Paketquellen bauen, müssen den Editor neu bündeln, damit die geänderte Konfiguration und die Schriftdateien wirksam werden; wer das Auslieferungspaket verwendet, erhält die fertigen Bundles mit.

Vorher / Nachher:

// Vorher (editor/src/themes/index.scss)
// Custom BS5 Style
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap');
// Nachher
// Custom BS5 Style
@import 'fonts';
// Neu (editor/src/themes/fonts.scss)
@font-face {
  font-family: 'IBM Plex Sans';
  font-weight: 100;
  font-style: normal;
  font-display: swap;
  src: url('../../../assets/fonts/ibm-plex-sans/IBMPlexSans-Thin.ttf');
}
// Neu (editor/rsbuild.config.js)
cssExtract: {
  loaderOptions: {
    // Resolve url() assets relative to the emitted CSS file so fonts load
    // regardless of the install path (root or subdirectory)
    publicPath: '../../',
  },
},

Nach dem Update testen: Den neuen Fragen-Editor mit geöffneter Netzwerkanalyse des Browsers aufrufen und prüfen, dass keine Anfrage an eine externe Schriftadresse mehr erscheint und alle Schriftdateien aus der eigenen Installation geladen werden. In einer Installation in einem Unterverzeichnis zusätzlich kontrollieren, dass die Schriftdateien nicht mit Statuscode 404 beantwortet werden.

Betroffene Dateien: editor/src/themes/fonts.scss, editor/src/themes/index.scss, editor/src/themes/customizations.scss, editor/rsbuild.config.js, editor/build/static/font

Relevante Commits: ad076313eb

A8: Überarbeitungen im neuen Fragen-Editor

Sicherheitsrelevanz
Keine
Handlungsdruck
Niedrig
Bruchverhalten
Fehler zur Laufzeit
Betroffen
Administratoren, Theme-Entwickler, Plugin-Entwickler

Hintergrund: Acht der 29 Commits dieses Release betreffen den neuen Fragen-Editor und machen damit den größten zusammenhängenden Block aus. Serverseitig verknüpft die Editor-Dienstklasse den Aktivierungsschalter des Editors jetzt mit dem Freigabekennzeichen: Sowohl die Konfiguration der Editor-Anwendung als auch der Aufbau des Seitenmenüs werten beide Werte gemeinsam aus. Auf der Oberflächenseite kommen die Vorschau für Fragengruppen und einzelne Fragen zurück, ein Tastaturkürzel zum Anlegen weiterer Antwort- und Unterfragenoptionen wird eingeführt, die Erzeugung von Frage- und Antwortcodes wird in einen gemeinsamen Hilfsmechanismus überführt, die Blätterschaltflächen der Tabellen werden neu aufgebaut, die Aufklappmenüs für Sprachumschaltung und Theme-Optionen erhalten geänderte Auszeichnung, und die Kopfzeile der Antworttabelle stellt Fragetexte mit Sonderzeichenkodierungen wieder korrekt dar.

Konsequenz: Administratoren sehen im Editor veränderte Bedienelemente und die zurückgekehrte Vorschaufunktion. Praktisch bedeutsam ist die serverseitige Verknüpfung: Wo der Editor eingeschaltet, aber nicht freigegeben ist, greifen Umleitung und Seitenmenü jetzt einheitlich, sodass die Oberfläche nicht mehr in einen Zwischenzustand gerät. Für Theme- und Plugin-Entwickler ist die Umschichtung der Editor-Bausteine außenwirksam, sobald eigene Anpassungen auf die Auszeichnung dieser Oberfläche zugreifen: Die Blätterschaltflächen wurden auf 181 geänderten Zeilen neu gebaut, die zugehörige Stilvorlage um 155 Zeilen erweitert, und die Aufklappmenüs sowie die Kopfzeile der Antworttabelle haben geänderte Struktur. Eigene Stilregeln oder Skripte, die an der bisherigen Struktur ansetzen, greifen dann ins Leere; das äußert sich als sichtbar fehlerhafte Darstellung oder als wirkungslose Erweiterung im Betrieb. Welche Auszeichnungsmerkmale im Einzelnen entfallen, ist nur aus den Quelldateien selbst ablesbar und wurde hier nicht vollständig aufgeschlüsselt.

Vorher / Nachher:

// Vorher (application/models/services/EditorService.php)
$editorConfig = new EditorConfig(self::$instance->editorStatus ?? false);
// Nachher
$editorConfig = new EditorConfig((self::$instance->editorStatus && self::$instance->editorAllowed) ?? false);

Nach dem Update testen: Den neuen Fragen-Editor öffnen und die Vorschau einer Fragengruppe sowie einer einzelnen Frage auslösen. Eine Frage mit Sonderzeichenkodierungen im Fragetext anlegen und die Kopfzeile der Antworttabelle prüfen. Anschließend mit einem Konto, für das der Editor nicht freigegeben ist, die Umfrageverwaltung aufrufen und kontrollieren, dass weder Umleitung noch Seitenmenü in den Editor führen. Eigene Stilvorlagen für die Verwaltungsoberfläche auf den Blätterschaltflächen und den Aufklappmenüs gegenprüfen.

Betroffene Dateien: application/models/services/EditorService.php, editor/src/components/UIComponents/PaginationButtons/PaginationButtons.js, editor/src/hooks/useChildKeyboardShortcuts.js, editor/src/components/Survey/QuestionGroups/QuestionGroupHeader.js, editor/src/components/ResponsesTable/ResponsesTableHeader.js

Relevante Commits: 6f907c6da6, 1233ab0570, e28f172601, 331fd1f7e9, 8ec559410b, 68788b06d0, 39654a528d

Weitere relevante Änderungen

Beispieldatei für den Teilnehmerimport
Survey Runtime · Kein Bruch · Administratoren, Integratoren
Eine neue Verwaltungsaktion liefert eine Beispieldatei mit den erwarteten Spalten aus, geschützt durch das Importrecht auf der Umfrage. (29b1723c50)

Auswahl über Seitengrenzen in der Umfragenliste
Performance · Kein Bruch · Administratoren, Plugin-Entwickler
Eine neue Route liefert alle gefilterten Umfragekennungen ohne Begrenzung der Ergebnismenge, was auf großen Installationen zu spürbar langen Antwortzeiten führen kann. (05b98debd7)

Massenbearbeitung von Teilnehmern bei Gesamtauswahl
Survey Runtime · Kein Bruch · Administratoren
Die Massenbearbeitung berücksichtigt jetzt auch Teilnehmer, die über die seitenübergreifende Gesamtauswahl markiert wurden, statt leer zu laufen. (71d90b83c5)

Bislang ausgeschlossenes Composer-Paket wird mitgeliefert
Plugin-Kompatibilität · Kein Bruch · Administratoren, Plugin-Entwickler
Ein bereits deklariertes, aber von der Versionsverwaltung ausgeschlossenes Paket wird jetzt mit ausgeliefert, wodurch der Statistikexport nach Excel wieder fehlerfrei läuft. (67eb29dd08)

Farbnotation der Theme-Variationen umgestellt
Themes und Rendering · Kein Bruch · Theme-Entwickler
Die acht ausgelieferten Variationsstilvorlagen wurden neu erzeugt und geben Farben nun als Hexadezimalwerte statt als Funktionsschreibweise mit Nachkommastellen aus. (50d90cacfc)

Mindestbreite für das Sonstiges-Eingabefeld
Themes und Rendering · Kein Bruch · Theme-Entwickler, Administratoren
Eine neue Regel setzt eine Mindestbreite für das Freitextfeld neben Einfachauswahl-Optionen, sodass es auf schmalen Bildschirmen bedienbar bleibt. (50d90cacfc)

Sammel-Commit 50d90cacfc; umfasst die 2 vorstehenden Einträge.

Sonstiges-Feld bei Bildauswahl wird geleert
Survey Runtime · Kein Bruch · Theme-Entwickler, Administratoren
Die Auszeichnung der Bildauswahl enthält jetzt zusätzlichen Skriptcode in den Ereignisattributen, der das Freitextfeld beim Wechsel der Auswahl leert. (57f7f02d24)

Vorschaumodus der Logikübersicht umgestellt
Survey Runtime · Kein Bruch · Administratoren
Der Vorschaumodus wird jetzt über die Umfrageoptionen gesetzt statt direkt am Ausdrucksverwalter, wodurch die Logikübersicht keinen Serverfehler mehr auslöst. (b2da414369)

Ladeanzeige der Dateneingabe wird wieder ausgeblendet
Survey Runtime · Kein Bruch · Administratoren
Das Bearbeitungsformular blendet die Ladeanzeige bei abgebrochener Prüfung wieder aus, sodass die Oberfläche nach einem fehlgeschlagenen Speichern bedienbar bleibt. (7466fcd59c)

Drag-and-Drop von Fragengruppen neu umgesetzt
Themes und Rendering · Kein Bruch · Administratoren
Die Reihenfolge der Fragengruppen wird beim Ziehen aus einer beim Ziehbeginn gesicherten Ausgangsreihenfolge berechnet statt aus paarweisem Tausch benachbarter Einträge. (0b27dff656)

Statusanzeige in der Benutzerliste
Themes und Rendering · Kein Bruch · Administratoren
Verneinende Werte erhalten in der Benutzerliste ein eigenes Symbol, und der Statusfilter ist mit Aktiv und Inaktiv statt mit Ja und Nein beschriftet. (a93925bfb2)

Zuordnung nach Bereich

BereichVollständig beschriebenWeitere Einträge
SicherheitA3, A7
DatenbankA1
RemoteControl APIkeine
Survey RuntimeA1, A2, A6ja
Themes und RenderingA6, A7, A8ja
Plugin-KompatibilitätA2, A4, A5, A8ja
Performancekeineja

Nicht betroffene Bereiche

Die folgenden Beobachtungen stützen sich darauf, welche Dateien im Diff zwischen den beiden Tags auftauchen; sie sind keine Garantie für die Abwesenheit jeder Auswirkung.

Die Handlerdateien der RemoteControl-Schnittstelle unterhalb von application/helpers/remotecontrol/ erscheinen nicht im Diff. Unverändert sind damit die dort festgelegten Methodennamen, ihre Parameter und die Namen der Rückgabefelder. Über die Werte in diesen Feldern sagt das nichts aus, siehe A1.

Das Aktualisierungswerkzeug unterhalb von application/helpers/update/ erscheint nicht im Diff, und die interne Datenbank-Versionsnummer bleibt gleich. Das Release enthält damit keine Schema-, Spalten-, Index- oder Constraint-Änderung.

// Vorher (application/config/version.php)
$config['versionnumber'] = '7.0.7';
$config['dbversionnumber'] = 709;
$config['buildnumber'] = '';
$config['updatable'] = true;
$config['templateapiversion']  = 3;
$config['assetsversionnumber'] = '30495';
// Nachher
$config['versionnumber'] = '7.0.8';
$config['dbversionnumber'] = 709;
$config['buildnumber'] = '';
$config['updatable'] = true;
$config['templateapiversion']  = 3;
$config['assetsversionnumber'] = '30496';

Die Klassen der Plugin-Verwaltung unterhalb von application/libraries/PluginManager/ und die mitgelieferten Kern-Plugins unterhalb von application/core/plugins/ erscheinen nicht im Diff. Ereignisnamen, deren Parameter und der Registrierungsweg für Plugins sind damit unverändert.

Die Dateien composer.json und composer.lock erscheinen nicht im Diff. Unverändert ist damit die Deklaration der Abhängigkeiten und ihrer Versionsstände. Welche Dateien der deklarierten Pakete tatsächlich mit ausgeliefert werden, ist eine davon getrennte Frage, siehe das Kapitel Weitere relevante Änderungen.

Die Datei application/config/config-defaults.php erscheint nicht im Diff. Die Standardwerte der Installationskonfiguration sind damit unverändert, und das Update legt keine neue Konfigurationsdatei an.

Empfehlung

Administratoren

Vor dem Update: Erfassen, ob in der Installation anonymisierte Umfragen mit aktivierter Zeitstempelung laufen, und für diese die bisherigen Zeitstempelwerte sichern oder zumindest den Umstellungszeitpunkt festhalten (A1). Prüfen, ob eine von der ermittelten abweichende öffentliche Basis-URL konfiguriert ist, und die derzeit erzeugten Mail-Adressen als Vergleichsgrundlage festhalten (A2). Eine Datenbank- und Dateisicherung anlegen. Feststellen, ob Themes installiert sind, deren API-Version nicht zur laufenden Version passt (A4).

Unmittelbar nach dem Update: Die Prüfschritte aus A1, A2 und A6 in dieser Reihenfolge abarbeiten, weil dort die stillen Verhaltensänderungen liegen. Danach eine Administrator-Benachrichtigung auslösen und die Verweise darin prüfen (A5). Anschließend den neuen Fragen-Editor mit geöffneter Netzwerkanalyse aufrufen (A7) und die Vorschaufunktionen bedienen (A8). Wer selbst aus den Paketquellen baut, muss den Editor neu bündeln, damit die lokale Schrifteinbindung wirksam wird (A7).

Rollback: Das Release enthält keine Datenbankmigration und legt keine neue Konfigurationsdatei an; beides ist oben durch das Zitat der Versionsdatei und die Beobachtung an application/config/config-defaults.php gedeckt. Ein Rückschritt auf den vorherigen Stand ist damit auf Dateiebene möglich, ohne dass Schemaänderungen rückgängig gemacht werden müssten. Nicht rückgängig zu machen sind die bereits geschriebenen Daten: Antwortdatensätze anonymisierter Umfragen, die nach dem Update entstanden sind, tragen den Platzhalterwert und behalten ihn auch nach einem Rückschritt (A1). Ob eine Wiederherstellung des vorherigen Standes für Installationen, in denen zwischenzeitlich Themes wegen Unverträglichkeit entfernt wurden, ohne Nacharbeit gelingt, ist aus dem Diff nicht bestimmbar (A4); das ist vorab in einer Testumgebung zu prüfen.

Plugin-Entwickler

Eigenen Code darauf durchsehen, ob die rekursive Theme-Deinstallation oder die Verträglichkeitsprüfung aufgerufen oder überschrieben wird, und die geänderten Rückgabetypen nachziehen (A4). Ersetzungen, die bisher über die globale Aktualisierung von Ersetzungsfeldern gesetzt wurden, auf die neue Mailer-Methode umstellen und dabei prüfen, ob eigene Platzhalter mit auf URL endendem Namen jetzt ungewollt als Verweis ausgezeichnet werden (A5). Erweiterungen, die auf Adressen aus der öffentlichen URL-Erzeugung aufbauen, gegen die neue Erzeugung prüfen (A2). Erweiterungen der Verwaltungsoberfläche gegen die umgebauten Editor-Bausteine testen (A8).

Theme-Entwickler

Eigene Ranking-Themes darauf prüfen, ob die Listenelemente das Attribut data-value tragen, weil die Auswahlübernahme sonst ohne Fehlermeldung ausfällt (A6). Abgeleitete Themes gegen die geänderten Rückgabewerte der Verträglichkeitsprüfung testen, insbesondere solche mit eigener Deinstallationslogik (A4). Eigene Anpassungen an der Verwaltungsoberfläche gegen die neu aufgebauten Blätterschaltflächen, Aufklappmenüs und die Kopfzeile der Antworttabelle prüfen (A8). Wer die ausgelieferten Variationsstilvorlagen als Vergleichsgrundlage pflegt, muss die umgestellte Farbnotation nachziehen, siehe das Kapitel Weitere relevante Änderungen. Die lokale Schrifteinbindung im Editor bei eigenen Bündelungen berücksichtigen (A7).

Integratoren

Auswertungen und Datenstrecken, die auf datestamp, startdate oder submitdate aufsetzen, für anonymisierte Umfragen prüfen und entscheiden, wie mit dem Platzhalterwert und dem daraus entstehenden gemischten Datenbestand umzugehen ist (A1). Regeln, die auf der Zeichengestalt erzeugter Umfrageadressen aufbauen, etwa in vorgelagerten Proxys oder beim Abgleich von Rücksprungadressen, gegen die neue URL-Erzeugung prüfen (A2). Automatisierte Ausfüllstrecken für Ranking-Fragen erneut durchlaufen lassen, weil sich sowohl die Pflichtprüfung als auch die Zuordnung zwischen Auswahlwert und Listenelement geändert hat (A6). Empfangende Systeme für Benachrichtigungsmails auf die jetzt verlinkten Platzhalter prüfen (A5).

API-Nutzer

Der Aufrufvertrag der RemoteControl-Schnittstelle ist unverändert, siehe das Kapitel Nicht betroffene Bereiche. Zu prüfen sind allein die gelieferten Werte: Abgerufene Antwortdatensätze anonymisierter Umfragen enthalten in den Zeitstempelfeldern ab dieser Version einen Platzhalterwert statt des tatsächlichen Zeitpunkts, was ohne Fehlermeldung durch die eigene Verarbeitung läuft (A1). Wer Mailversand über die Schnittstelle anstößt und dabei eigene Ersetzungen mitgibt, sollte die Darstellung von Platzhaltern mit auf URL endendem Namen kontrollieren (A5).