Kopfdaten und Grenzen
- Release
- 7.0.1 → 7.0.2
- Commits
- 27
- Geänderte Dateien
- 687
- Analyse
- 11.08.2026
- Schwerpunkt
- Barrierefreiheit und Stabilisierung
Nicht untersucht
Verglichen wurden die Tags 7.0.1+260611 mit Commit-Datum 10. Juni 2026 und 7.0.2+260617 mit Commit-Datum 16. Juni 2026 mit den Befehlen git log --oneline 7.0.1+260611..7.0.2+260617 und git diff --stat 7.0.1+260611..7.0.2+260617; beide Tags sind im Repository vorhanden. Nicht ausgewertet wurden die minifizierten Ableitungen der geänderten Quelldateien, die Sprachdateien unter locale, der kompilierte React-Build unter editor/build sowie der Bundle-Inhalt der aktualisierten Pakete unter node_modules jenseits ihrer Versionsangaben; damit bleibt offen, ob diese Bundles Verhaltensänderungen enthalten, die über die hier beschriebenen hinausgehen. Indirekte Effekte über transitive Drittabhängigkeiten sind durch eine reine Diff-Analyse nicht vollständig erfassbar. Aus dem Kapitel „Weitere relevante Änderungen" wurden keine Einträge ausgelassen.
Executive Summary
Dieses Release ist zur Hälfte ein Barrierefreiheits-Release: 13 der 27 Commits bauen das Markup der Administrationsoberfläche um, damit Tabs, Modaldialoge, Formulare und Tabellen für Screenreader und Tastaturbedienung korrekt ausgezeichnet sind. Die zweite Hälfte besteht aus Stabilisierungen rund um Vorschau, Editor, Laufzeitverzeichnisse und Hostprüfung. Am ehesten unbemerkt kaputt geht eigenes CSS, JavaScript oder Testautomatisierung, das sich auf die bisherige Struktur der Administrationsansichten stützt — insbesondere auf die Bestätigungsschaltfläche in Modaldialogen, die vom Anker zum Button gewechselt ist, und auf eine umbenannte Element-Kennung im Bestätigungsdialog. Unbemerkt ungelöst bleibt dagegen nichts Erkennbares aus dem Vorgängerrelease.
- Schaltflächen in Modaldialogen sind jetzt Button-Elemente
- Barrierefreiheitsumbau ändert Markup und Kennungen der Administrationsansichten
- Vorschau der Themeoptionen legt keine leeren Antwortdatensätze mehr an
- CKEditor wird nicht mehr über den Asset-Manager veröffentlicht
- Fehlgeschlagenes Schreiben der Datei erlaubter Hosts wird jetzt gemeldet
- Erlaubte Hosts lassen sich jetzt in der Hauptkonfiguration setzen
- Laufzeitverzeichnisse werden angelegt und ihre Zugriffssperre wandert in die Wurzeldatei
- Neue Sperrdatei und Hauptversionssprung der PDF-Bibliothek
Upgrade-Empfehlung
🧪 Vorher testen
Das Release enthält keine Datenbankmigration und keine angehobene Mindestanforderung, verändert aber an vielen Stellen das ausgelieferte Markup der Administrationsoberfläche und die Auslieferung des CKEditor-Pakets. Wer eigene Administrationsthemes, Plugins mit eigenem JavaScript oder Testautomatisierung betreibt, sollte diese Punkte vor dem Produktivupdate in einer Testumgebung prüfen. Für Installationen ohne solche Anpassungen ist das Update unproblematisch.
Lesepfad
| Zielgruppe | Relevante Kennungen und Kapitel |
|---|---|
| Administratoren | A3, A4, A5, A6, A7, A8, Weitere relevante Änderungen, Empfehlung |
| Plugin-Entwickler | A1, A2, A3, A4, A8, Weitere relevante Änderungen, Empfehlung |
| Theme-Entwickler | A1, A2, A3, A4, Weitere relevante Änderungen, Empfehlung |
| Integratoren | A1, A2, A3, A6, A8, Weitere relevante Änderungen, Empfehlung |
| API-Nutzer | A6, Empfehlung |
Die wichtigsten Änderungen
A1: Schaltflächen in Modaldialogen sind jetzt Button-Elemente
Hintergrund: Die sieben gemeinsam genutzten Modalfußzeilen unter application/views/layouts/partial_modals stellten die bestätigende Schaltfläche bisher als Ankerelement mit role="button" und tabindex="0" dar. Ein Anker ohne href wird von Browsern nicht als Bedienelement aktiviert, sodass die Schaltfläche per Tastatur nicht auslösbar war. Alle sieben Partials liefern die Schaltfläche jetzt als echtes button-Element mit type="button" aus. Die Klassen btn, btn-ok und die jeweilige Variantenklasse bleiben unverändert.
Konsequenz: Jeder Selektor, der die Bestätigungsschaltfläche über den Elementtyp anspricht, greift nicht mehr. Betroffen sind CSS-Regeln der Form a.btn-ok, jQuery-Delegationen auf a.btn-ok und Testautomatisierung, die den Knopf über seinen Linktext findet. Der Bruch ist still: Die Modaldialoge werden weiterhin gerendert, nur greifen die eigenen Regeln und Handler nicht mehr. Wer ausschließlich über die Klasse .btn-ok selektiert, ist nicht betroffen. Die LimeSurvey-eigene Testsuite wurde im selben Commit angepasst und zeigt damit exemplarisch, welche Art von Selektor umgestellt werden muss.
Vorher / Nachher:
// Vorher (application/views/layouts/partial_modals/modal_footer_canceldelete.php)
<a role="button" class="btn btn-danger btn-ok" tabindex="0">
<?php eT("Delete"); ?>
</a>
// Nachher
<button type="button" class="btn btn-danger btn-ok">
<?php eT("Delete"); ?>
</button>
// Vorher (tests/functional/acceptance/19201-user-status/UserStatusTest.php)
// Click "Apply"
$web->findByLinkText('Apply')->click();
// Nachher
$web->findByCss('.modal.show .btn-ok')->click();
Nach dem Update testen: Eine Massenaktion in der Benutzerverwaltung oder der Umfrageliste ausführen und prüfen, ob die Bestätigungsschaltfläche im Modal per Mausklick und per Tastatur mit Tabulator und Eingabetaste auslöst. Anschließend das eigene Administrationstheme und alle eigenen Skripte nach den Zeichenfolgen btn-ok und findByLinkText durchsuchen und die Treffer auf Elementtyp-Annahmen prüfen.
Betroffene Dateien: application/views/layouts/partial_modals/modal_footer_cancelsave.php, application/views/layouts/partial_modals/modal_footer_canceldelete.php, application/views/layouts/partial_modals/modal_footer_cancelapply.php, application/views/layouts/partial_modals, tests/functional/acceptance/19201-user-status/UserStatusTest.php
Relevante Commits: 48ed0f4bd6
A2: Barrierefreiheitsumbau ändert Markup und Kennungen der Administrationsansichten
Hintergrund: Zwölf weitere Commits überarbeiten das Markup der Administrationsoberfläche nach ARIA-Gesichtspunkten. Die Tabreiter in der Plugin-Konfiguration, den persönlichen Einstellungen und der Umfragemenü-Verwaltung erhalten Kennungen, aria-controls, aria-selected und eine gesteuerte Tabulatorreihenfolge; die zugehörigen Tabpanels werden über aria-labelledby an ihren Reiter gebunden. Die Massenbearbeitungsformulare der Umfragemenüs werden in fieldset-Elemente mit versteckter Legende gefasst, ihre Auswahllisten erhalten feste Kennungen. Modaltitel wechseln von h5 auf h2 mit beibehaltener Größenklasse, das Benachrichtigungsmenü verliert sein role='menu' und bekommt aria-haspopup und aria-controls, die Seitenblätterung erzeugt kontextbezogene aria-label-Werte, und die Übersichtstabellen erhalten eine caption.
Konsequenz: Eigene CSS-Regeln und eigenes JavaScript, die sich auf die bisherige Struktur stützen, greifen teilweise nicht mehr, ohne dass ein Fehler sichtbar wird. Der konkreteste Fall ist der Bestätigungsdialog in der Fußzeile der Administrationsoberfläche: Dessen Titel trug bisher die Kennung confirmationModalTitle und heißt jetzt confirmation-modal-title. Wer diese Kennung in eigenem CSS oder JavaScript verwendet, verliert die Referenz kommentarlos. Ebenso entfällt am Knopf zum Anlegen eines Umfragemenüs das title-Attribut, und Selektoren auf h5.modal-title treffen die umgestellten Dialoge nicht mehr. Ob eigene Anpassungen im Einzelfall betroffen sind, hängt davon ab, wie spezifisch sie selektieren; pauschal lässt sich das aus dem Diff nicht bestimmen. Im Formular für Umfragemenüs steckt zusätzlich eine funktionale Korrektur: Die Reihenfolge wird beim Bearbeiten eines bestehenden Menüs nicht mehr auf die nächste freie Position zurückgesetzt.
Vorher / Nachher:
// Vorher (application/views/admin/super/footer.php)
<div id="confirmation-modal" class="modal fade" role="dialog" aria-labelledby="confirmationModalTitle" aria-modal="true">
...
<h5 class="modal-title" id="confirmationModalTitle"><?php eT("Confirm"); ?></h5>
// Nachher
<div id="confirmation-modal" class="modal fade" role="dialog" aria-modal="true"
aria-labelledby="confirmation-modal-title">
...
<h2 class="h5 modal-title" id="confirmation-modal-title"><?php eT("Confirm"); ?></h2>
// Vorher (application/views/admin/surveymenu/_form.php)
<?php $model->ordering = $model->getNextOrderPosition(); ?>
// Nachher
<?php $model->ordering = $model->isNewRecord ? $model->getNextOrderPosition() : $model->ordering; ?>
// Neu (application/extensions/admin/grid/CLSYiiPager.php)
$ariaLabel = '';
if (is_numeric($label)) {
if ($selected) {
$ariaLabel = sprintf(gT('Page %s, current page'), $label);
} else {
$ariaLabel = sprintf(gT('Go to page %s'), $label);
}
}
Nach dem Update testen: Die persönlichen Einstellungen, die Plugin-Konfiguration und die Umfragemenü-Verwaltung öffnen und die Tabreiter ausschließlich per Tastatur bedienen. Ein bestehendes Umfragemenü bearbeiten und speichern, dann prüfen, ob seine Reihenfolge unverändert geblieben ist. Das eigene Administrationstheme nach confirmationModalTitle, h5.modal-title und role='menu' durchsuchen.
Betroffene Dateien: application/views/admin/super/footer.php, application/views/admin/user/personalsettings.php, application/views/admin/pluginmanager/configure.php, application/extensions/admin/grid/CLSYiiPager.php, application/views/admin/surveymenu
Relevante Commits: ef14f90d95, 136fb3d979, 00c447fb19, 1f6e723e8f, 959251574f, 8a64a32465, 0a8aeb65f5, 5e511004b7, aab1a84ed0, 714cb4236d, 77e4937e2f, de7bf17e83
A3: Vorschau der Themeoptionen legt keine leeren Antwortdatensätze mehr an
Hintergrund: Die Vorschau in den Themeoptionen ruft die Umfrage mit dem Parameter popuppreview auf. Bisher wurde dieser Parameter zwar für die Darstellungsoptionen ausgewertet, führte aber nicht dazu, dass der eigentliche Vorschaumodus gesetzt wurde. Der Expression Manager erhielt damit keine Kenntnis vom Vorschaubetrieb und schrieb Antwortdatensätze in die Antworttabelle der aktiven Umfrage. Der Controller setzt den Vorschaumodus jetzt bereits beim Erkennen von popuppreview, der Umfrage-Laufzeithelfer reicht ihn über die Umfrageoptionen weiter, und der Expression Manager übernimmt ihn beim Aufbau seiner Optionen, weil sein interner Zustand zwischenzeitlich zurückgesetzt wird. Ein Folgecommit desselben Pull-Requests räumt den Controller auf und vereinheitlicht die Berechtigungsprüfung für alle drei Vorschauarten.
Konsequenz: Wer die Vorschau in den Themeoptionen einer aktiven Umfrage öffnet, erzeugt keine leeren Antwortdatensätze mehr. Bestehende leere Datensätze werden dadurch nicht entfernt; sie bleiben in der Antworttabelle und müssen bei Bedarf manuell bereinigt werden. Zwei Nebenwirkungen sind zu beachten. Erstens läuft der Aufruf mit popuppreview jetzt durch denselben Zweig wie die Gruppen- und Fragenvorschau und beendet dabei eine laufende Umfragesitzung für dieselbe Umfrage im selben Browser; wer parallel im selben Browser an der Umfrage teilnimmt, verliert diesen Fortschritt. Zweitens liefert die Anwendungskonfiguration unter dem Schlüssel previewmode für popuppreview-Aufrufe nun den Wert true statt false; Plugins, die diesen Wert auswerten, sehen ein verändertes Verhalten. Ob eigener Code, der den Umfrage-Laufzeithelfer direkt aufruft, den neuen Schlüssel previewmode in seinen Argumenten mitliefert, ist aus dem Diff nicht bestimmbar — der Zugriff darauf erfolgt ohne Absicherung.
Vorher / Nachher:
// Vorher (application/controllers/survey/SurveyIndex.php)
$previewmode = false;
if (isset($param['action']) && (in_array($param['action'], array('previewgroup', 'previewquestion')))) {
// Nachher
$previewmode = false;
$popuppreview = (bool)Yii::app()->request->getParam('popuppreview', false);
if ($popuppreview
|| (
isset($param['action'])
&& (in_array($param['action'], ['previewgroup', 'previewquestion']))
)
) {
// Neu (application/helpers/SurveyRuntimeHelper.php)
$this->aSurveyOptions['previewmode'] = $args['previewmode'];
// Neu (application/helpers/expressions/em_manager_helper.php)
// make sure to get the previewmode set by aSurveyOptions because LEM reset happens inbetween
self::SetPreviewMode($aSurveyOptions['previewmode'] ?? false);
Nach dem Update testen: Bei einer aktiven Umfrage die Anzahl der Datensätze in der Antworttabelle notieren, die Themeoptionen öffnen, die Vorschau starten und die Anzahl erneut prüfen — sie muss unverändert bleiben. Anschließend die Gruppen- und Fragenvorschau eines Nichtberechtigten aufrufen und prüfen, dass weiterhin 401 beziehungsweise 403 zurückkommt.
Betroffene Dateien: application/controllers/survey/SurveyIndex.php, application/helpers/SurveyRuntimeHelper.php, application/helpers/expressions/em_manager_helper.php
Relevante Commits: dc13703c52, 5d430d5426
A4: CKEditor wird nicht mehr über den Asset-Manager veröffentlicht
Hintergrund: Die Konfiguration von CKEditor baut die Adressen des Dateibrowsers relativ zum eigenen Basispfad auf und erwartet das KCFinder-Paket als Geschwisterverzeichnis. Sobald der Asset-Manager das CKEditor-Paket in ein gehashtes Unterverzeichnis unterhalb des temporären Verzeichnisses kopierte, zeigte dieser relative Pfad ins Leere und der Bildupload im Editor schlug fehl. Die Client-Script-Komponente führt jetzt eine Ausnahmeliste, deren Pakete grundsätzlich nicht über den Asset-Manager veröffentlicht, sondern direkt aus dem Paketverzeichnis ausgeliefert werden. Diese Liste enthält derzeit ausschließlich das CKEditor-Paket.
Konsequenz: Bild- und Dateiupload im Editor funktionieren wieder, unabhängig davon, ob der Asset-Manager aktiviert ist. Als Gegenleistung wird das CKEditor-Paket nun in jeder Betriebsart direkt aus dem Paketverzeichnis ausgeliefert. Installationen, die den Webzugriff auf dieses Verzeichnis eingeschränkt haben oder ausgelieferte Skripte ausschließlich über das temporäre Verzeichnis bereitstellen, verlieren dadurch den Editor. Die Ausnahmeliste ist als geschützte Eigenschaft angelegt und damit nur durch Ableitung der Klasse erweiterbar; ein Konfigurationsschlüssel dafür ist im Diff nicht erkennbar. Die Umleitung greift nur, wenn das Paket unter dem Namen ckeditor registriert wird, und nicht für Pakete, die CKEditor lediglich als Abhängigkeit führen.
Vorher / Nachher:
// Neu (application/core/LSYii_ClientScript.php)
protected $packagesNotPublishedByAssetManager = ['ckeditor'];
// Neu (application/core/LSYii_ClientScript.php)
if (in_array($name, $this->packagesNotPublishedByAssetManager)) {
$this->convertDevBaseUrl($name);
parent::registerPackage($name);
return;
}
Nach dem Update testen: Eine Frage oder einen Textbaustein im Editor öffnen, über die Bildschaltfläche den Dateibrowser aufrufen und ein Bild hochladen. In den Entwicklerwerkzeugen prüfen, dass die Adresse von ckeditor.js auf das Paketverzeichnis und nicht auf das temporäre Verzeichnis zeigt, und dass keine 404-Antwort für den Dateibrowser auftritt.
Betroffene Dateien: application/core/LSYii_ClientScript.php, application/config/packages.php
Relevante Commits: 02a9601546
A5: Fehlgeschlagenes Schreiben der Datei erlaubter Hosts wird jetzt gemeldet
Hintergrund: Beim ersten Anmelden eines Administrators legt LimeSurvey die Datei der vertrauenswürdigen Hosts im Konfigurationsverzeichnis an und schützt die Installation damit gegen Host-Header-Injection. Bisher wurde das Ergebnis des Schreibvorgangs nur intern ausgewertet: Schlug es fehl, weil das Konfigurationsverzeichnis nicht beschreibbar war, geschah nichts Sichtbares. Die schreibende Methode prüft die Schreibbarkeit jetzt vorab, protokolliert Fehlschläge mit einer eigenen Kategorie und meldet den Fehler an den Aufrufer; der Anmeldecontroller zeigt in diesem Fall eine Warnung an.
Konsequenz: Administratoren erfahren nach dem Update beim Anmelden, wenn die Hostprüfung mangels beschreibbarem Konfigurationsverzeichnis nicht aktiv ist. Die Änderung aktiviert den Schutz nicht selbst — sie macht sein Fehlen sichtbar. Installationen, in denen das Konfigurationsverzeichnis bewusst schreibgeschützt ist, sehen die Warnung bei jeder Anmeldung, solange sie den Schlüssel nicht manuell setzen. Die Warnung erscheint nur im Anmeldepfad der Administrationsoberfläche; für Aufrufe über die Konsole ist im Diff kein entsprechender Hinweis erkennbar, dort schlägt lediglich die Protokollierung an.
Vorher / Nachher:
// Vorher (application/core/Traits/LSApplicationTrait.php)
$result = @file_put_contents($filePath, $content);
if ($result !== false) {
// Update running config so the change takes effect immediately
Yii::app()->setConfig('allowedHosts', $sanitized);
}
return $result !== false;
// Nachher
$result = @file_put_contents($filePath, $content);
if ($result === false) {
$error = error_get_last();
Yii::log(
"Unable to write allowed hosts file '$filePath'." . (isset($error['message']) ? ' ' . $error['message'] : ''),
CLogger::LEVEL_ERROR,
'application.security.allowedHosts'
);
return false;
}
...
// Neu (application/core/Traits/LSApplicationTrait.php)
// Check that the target directory is writable before attempting to write,
// so we can report the failure instead of failing silently.
$configDir = dirname($filePath);
if ((!file_exists($filePath) && !is_writable($configDir)) || (file_exists($filePath) && !is_writable($filePath))) {
Yii::log(
"Unable to write allowed hosts file '$filePath': the file or its directory is not writable.",
CLogger::LEVEL_ERROR,
'application.security.allowedHosts'
);
return false;
}
// Neu (application/controllers/admin/Authentication.php)
} else {
Yii::app()->setFlashMessage(
gT('The allowed hosts file (application/config/allowed_hosts.php) could not be created because the application/config directory is not writable. No trusted host restriction is currently enforced. Please make the directory writable, then login again, to enable host header protection.'),
'warning'
);
}
Konfiguration: Betroffen ist die Datei application/config/allowed_hosts.php. Sie wird beim ersten Administratorlogin erzeugt, wenn das Verzeichnis beschreibbar ist. Fehlt sie, gilt keine Hostbeschränkung, und es erscheint künftig die oben zitierte Warnung. Das Dateiformat selbst ist im Diff nicht enthalten. Kein wörtliches Zitat verfügbar. Wer die Beschränkung ohne beschreibbares Verzeichnis setzen möchte, verwendet stattdessen den in A6 beschriebenen Konfigurationsschlüssel.
Nach dem Update testen: Abmelden, das Konfigurationsverzeichnis testweise schreibgeschützt setzen, erneut anmelden und prüfen, ob die Warnung erscheint und ein Eintrag mit der Kategorie application.security.allowedHosts im Anwendungsprotokoll steht. Danach die Schreibrechte wiederherstellen, erneut anmelden und prüfen, ob die Datei angelegt wird.
Betroffene Dateien: application/core/Traits/LSApplicationTrait.php, application/controllers/admin/Authentication.php
Relevante Commits: 4081fe0e70
A6: Erlaubte Hosts lassen sich jetzt in der Hauptkonfiguration setzen
Hintergrund: Die Hostprüfung gegen Host-Header-Injection im Passwort-Reset stammt aus einem früheren Release und bezog ihre Liste bisher ausschließlich aus der automatisch erzeugten Datei im Konfigurationsverzeichnis. Der zugehörige Schlüssel war in den Standardwerten nicht deklariert und damit weder dokumentiert noch offensichtlich überschreibbar. Die Standardkonfiguration deklariert ihn jetzt mit dem Wert null und erläutert Zweck, erwarteten Datentyp und Fehlerverhalten im Kommentar. Die Commit-Nachricht weist die Änderung als Folgearbeit zu Issue #19639 mit der Bezeichnung „Host Header Injection in password reset function" aus und verweist auf Pull-Request #5037; eine CVE-Kennung ist im Repository nicht auffindbar.
Konsequenz: Administratoren können die Liste vertrauenswürdiger Hosts nun in der Hauptkonfigurationsdatei setzen. Da die Standardwerte zuerst geladen werden, danach die Datei der erlaubten Hosts und zuletzt die Hauptkonfiguration, gewinnt ein dort gesetzter Wert gegenüber der automatisch erzeugten Datei. Der deklarierte Standardwert null verändert das Verhalten bestehender Installationen nicht, weil die Standardwerte vor der Hostdatei zusammengeführt werden. Für API-Nutzer ist relevant, dass Anfragen mit einem nicht gelisteten Host laut Kommentar mit Fehler 400 beantwortet werden — wer RemoteControl über einen internen Hostnamen oder eine IP-Adresse anspricht, muss diesen Namen mit aufnehmen. Ob die Prüfung auch dann greift, wenn der Host über einen Reverse-Proxy gesetzt wird, ist aus dem Diff nicht bestimmbar.
Vorher / Nachher:
// Neu (application/config/config-defaults.php)
// Allowed host of the LimeSurvey instance, avoid Host Header Injection in some case
// For security purpose : Host Header Injection in password reset function
// You can set an array of string, for example : ['example.limesurvey.org','limesurvey.example.org']
// Send a 400 error if the server host is not in this list.
$config['allowedHosts'] = null;
Konfiguration: Der Schlüssel wird in application/config/config-defaults.php deklariert und ist in application/config/config.php innerhalb des config-Abschnitts überschreibbar. Als Wert erwartet er nach dem zitierten Kommentar ein Array von Zeichenketten, etwa ['example.limesurvey.org','limesurvey.example.org'] — example.limesurvey.org ist dabei ein illustrativer Platzhalter aus dem Original. Wird der Schlüssel nicht gesetzt, bleibt es beim Standardwert null, und es gilt die Liste aus der Datei der erlaubten Hosts; existiert auch diese nicht, gilt keine Beschränkung.
Nach dem Update testen: Den Schlüssel in der Hauptkonfiguration mit dem eigenen Hostnamen setzen, die Administrationsoberfläche unter genau diesem Namen aufrufen und prüfen, dass die Anmeldung funktioniert. Anschließend dieselbe Instanz über einen nicht gelisteten Hostnamen aufrufen und prüfen, ob eine 400-Antwort kommt.
Betroffene Dateien: application/config/config-defaults.php, application/core/LSYii_Application.php, application/core/Traits/LSApplicationTrait.php
Relevante Commits: c785783b37
A7: Laufzeitverzeichnisse werden angelegt und ihre Zugriffssperre wandert in die Wurzeldatei
Hintergrund: Wird der Inhalt des temporären Verzeichnisses geleert — etwa durch ein Aufräumskript oder beim Ausrollen einer neuen Version — fehlten anschließend das Laufzeitverzeichnis und das Asset-Verzeichnis, und Yii brach mit einer Ausnahme ab. Web- und Konsolenanwendung legen beide Verzeichnisse jetzt bei Bedarf selbst an. Weil dabei auch die bisher im Laufzeitverzeichnis liegende Zugriffssperre verlorenginge, wurden die entsprechenden Regeln zusätzlich in die Wurzeldatei der Apache-Konfiguration aufgenommen; die ursprüngliche Datei im Laufzeitverzeichnis wurde im selben Release wieder ergänzt und ist im Vergleich beider Tags unverändert.
Konsequenz: Nach dem Leeren des temporären Verzeichnisses startet die Anwendung wieder, ohne dass die Verzeichnisse von Hand angelegt werden müssen. Der Schutz der Protokoll- und Cachedateien hängt nun nicht mehr allein an einer Datei innerhalb des temporären Verzeichnisses. Die neuen Regeln greifen nur unter Apache mit ausgewerteter Wurzeldatei; unter nginx, IIS oder bei abgeschalteter Auswertung von Verzeichniskonfigurationsdateien wirken sie nicht und müssen in der Serverkonfiguration nachgebildet werden. Ebenso greifen sie nicht, wenn das temporäre Verzeichnis über die Konfiguration an einen anderen Ort gelegt wurde, da die Regeln auf den Pfad tmp/runtime/ unterhalb des Anwendungswurzelverzeichnisses gemünzt sind. Das Anlegen erfolgt mit unterdrückter Fehlerausgabe; fehlen die Schreibrechte im übergeordneten Verzeichnis, bleibt der Zustand wie bisher.
Vorher / Nachher:
# Neu (.htaccess)
# deny access to the runtime directory (cache files, application.log, plugin.log)
# kept here so protection survives clearing the tmp directory content
RewriteRule ^tmp/runtime/ - [F]
...
# deny access to the runtime directory without mod_rewrite
RedirectMatch 403 ^/(.*/)?tmp/runtime/
// Neu (application/core/LSYii_Application.php)
/* Make sure the runtime path exists, e.g. after the tempdir content was cleared */
if (!is_dir($aApplicationConfig['runtimePath'])) {
@mkdir($aApplicationConfig['runtimePath'], 0775, true);
}
Konfiguration: Betroffen ist die Datei .htaccess im Anwendungswurzelverzeichnis. Die beiden zitierten Blöcke sind zu übernehmen: der erste innerhalb des vorhandenen IfModule-Abschnitts für die Rewrite-Regeln, der zweite außerhalb davon neben den bestehenden RedirectMatch-Regeln. Wurde die Datei lokal angepasst, überschreibt das Update sie nicht zwingend — fehlen die Regeln danach, bleibt der Zugriffsschutz auf dem Stand der Vorversion, also allein auf die Datei im Laufzeitverzeichnis gestützt.
Nach dem Update testen: Den Inhalt des temporären Verzeichnisses leeren, die Administrationsoberfläche aufrufen und prüfen, dass sie ohne Ausnahme startet und die Verzeichnisse neu entstanden sind. Anschließend im Browser https://example.org/tmp/runtime/application.log aufrufen — example.org ist ein Platzhalter für die eigene Domain — und prüfen, dass eine 403-Antwort kommt.
Betroffene Dateien: .htaccess, application/core/LSYii_Application.php, application/core/ConsoleApplication.php, tmp/runtime/.htaccess
Relevante Commits: bbfcf87165, cddcdabac8
A8: Neue Sperrdatei und Hauptversionssprung der PDF-Bibliothek
Hintergrund: Mit der Aktualisierung der npm-Pakete kommt erstmals eine yarn.lock in das Repository, und jspdf wird in package.json von ^3.0.0 auf ^4.2.1 gehoben. Das mitgelieferte Bundle unter node_modules wechselt entsprechend von Version 3.0.1 auf 4.2.1. Die Bibliothek wird als Asset-Paket registriert und vom PDF-Export der Statistik verwendet.
Konsequenz: Wer seine Installation selbst aus den Paketquellen baut, arbeitet ab jetzt gegen eine festgeschriebene Auflösung der npm-Abhängigkeiten; ein Build mit einem anderen Paketmanager kann von dieser Auflösung abweichen. Der Sprung über eine Hauptversion der PDF-Bibliothek bringt ein Risiko für eigene Erweiterungen mit sich, die dasselbe Asset-Paket registrieren und dessen API verwenden. Der Statistik-Export von LimeSurvey selbst nutzt nur den globalen Namensraum jspdf, den Konstruktor sowie die Methoden zum Hinzufügen von Bildern und Seiten; dieser globale Namensraum bleibt im neuen Bundle erhalten. Vermutung: Der Export bleibt damit funktionsfähig — belegbar ist das aus dem Diff nicht, da das Bundle nur in minifizierter Form vorliegt und nicht auf Verhaltensänderungen untersucht wurde.
Vorher / Nachher:
package.json, vorher:
"jspdf": "^3.0.0",
package.json, nachher:
"jspdf": "^4.2.1",
node_modules/jspdf/package.json, vorher:
"version": "3.0.1",
node_modules/jspdf/package.json, nachher:
"version": "4.2.1",
# Neu (yarn.lock)
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
Nach dem Update testen: In der Statistik einer Umfrage mit Diagrammen den PDF-Export ausführen und prüfen, dass eine vollständige Datei mit allen Seiten entsteht. Bei einem Eigenbau aus den Paketquellen den Build einmal vollständig neu durchführen und die Konsolenausgabe auf Auflösungskonflikte prüfen.
Betroffene Dateien: package.json, yarn.lock, application/config/vendor.php, assets/scripts/admin/createpdf_worker.js, node_modules/jspdf
Relevante Commits: 9c67c6925c
Weitere relevante Änderungen
Stapelbearbeitung der Umfragemenüs greift wieder
Themes und Rendering · Kein Bruch · Administratoren, Integratoren
Beim Stapelbearbeiten von Umfragemenüs werden Position, übergeordnetes Menü, Umfrage und Benutzer jetzt tatsächlich gespeichert statt stillschweigend verworfen. (6228582b87)
Seitenleiste der Statistikdiagramme korrigiert
Themes und Rendering · Kein Bruch · Administratoren
Die Seitenleiste der Diagrammansicht in der Statistik nutzt wieder die volle Höhe des Inhaltsbereichs. (fc1996f8fc)
Mitgelieferte JavaScript-Bibliotheken aktualisiert
Themes und Rendering · Kein Bruch · Administratoren, Plugin-Entwickler, Theme-Entwickler
Mehrere mitgelieferte JavaScript-Bibliotheken wurden auf neuere Stände gehoben, darunter der Codeeditor der Administrationsoberfläche und die Diagrammbibliothek. (8d7f48a4a1)
Interne Assetsnummer angehoben
Themes und Rendering · Kein Bruch · Administratoren, Theme-Entwickler
Die interne Assetsnummer steigt um eins, wodurch die Anwendung ihre ausgelieferten Skripte und Stylesheets nach dem Update neu veröffentlicht. (5a01c4189e)
Zuordnung nach Bereich
| Bereich | Vollständig beschrieben | Weitere Einträge |
|---|---|---|
| Sicherheit | A5, A6, A7 | – |
| Datenbank | A3 | – |
| RemoteControl API | keine | – |
| Survey Runtime | A3 | – |
| Themes und Rendering | A1, A2, A4, A8 | ja |
| Plugin-Kompatibilität | A1, A2, A3, A4, A8 | – |
| Performance | keine | – |
Nicht betroffene Bereiche
Diese Aussagen sind Beobachtungen am Diff der beiden Tags, keine Garantien.
Datenbankschema. Das Release enthält keine Migration. Die interne Datenbank-Versionsnummer ist vor und nach dem Update identisch, und im Diff erscheint keine Datei unterhalb der Aktualisierungshelfer und keine Datei mit der Endung .sql. Aussagen über Spalten, Indizes oder Constraints stützen sich ausschließlich auf diese Abwesenheit.
// Vorher (application/config/version.php)
$config['versionnumber'] = '7.0.1';
$config['dbversionnumber'] = 708;
$config['buildnumber'] = '';
$config['updatable'] = true;
$config['templateapiversion'] = 3;
$config['assetsversionnumber'] = '30489';
// Nachher
$config['versionnumber'] = '7.0.2';
$config['dbversionnumber'] = 708;
$config['buildnumber'] = '';
$config['updatable'] = true;
$config['templateapiversion'] = 3;
$config['assetsversionnumber'] = '30490';
- RemoteControl API. Im Diff erscheint keine Datei unterhalb von
application/helpers/remotecontrol. Die dort definierten Methoden, ihre Parameter und ihre Rückgabefelder sind damit unverändert. - Teilnehmeransicht der Umfragethemes. Im Diff erscheint keine Datei mit der Endung
.twigund keine Datei unterhalb vonthemes/survey. Die Version der Theme-API bleibt bei dem oben zitierten Wert. - PHP-Abhängigkeiten. Im Diff erscheinen weder
composer.jsonnochcomposer.lock. Die über Composer aufgelösten Bibliotheken und die dort hinterlegte PHP-Anforderung bleiben damit auf dem Stand der Vorversion. - Plugin-Infrastruktur. Im Diff erscheint keine Datei unterhalb von
application/libraries/PluginManager. Die Signaturen vonPluginEventund die Registrierung von Ereignissen sind unverändert; die in A3 beschriebene Änderung betrifft den Inhalt eines Konfigurationswerts, nicht den Mechanismus.
Empfehlung
Administratoren
Vor dem Update: Prüfen, ob der Webserver die Verzeichniskonfigurationsdatei im Anwendungswurzelverzeichnis auswertet; ist das nicht der Fall, die beiden neuen Sperrregeln vorab in der Serverkonfiguration nachbilden (A7). Prüfen, ob der Webzugriff auf das Paketverzeichnis der Assets eingeschränkt ist, und die Einschränkung gegebenenfalls lockern (A4). Bei einem Eigenbau aus den Paketquellen den bisherigen Build-Stand sichern (A8). Ein Datenbank-Backup ist wie immer ratsam, auch wenn dieses Release keine Migration enthält.
Unmittelbar nach dem Update: Anmelden und prüfen, ob die Warnung zur nicht schreibbaren Hostdatei erscheint; falls ja, entweder das Konfigurationsverzeichnis beschreibbar machen oder die Hostliste in der Hauptkonfiguration setzen (A5, A6). Bildupload im Editor testen (A4). Bei aktiven Umfragen die Vorschau der Themeoptionen aufrufen und die Antworttabelle auf neue Datensätze prüfen; bereits vorhandene leere Datensätze aus der Vorversion gegebenenfalls bereinigen (A3). PDF-Export der Statistik einmal ausführen (A8).
Rollback: Das Release legt keine Datenbankmigration an — die interne Datenbank-Versionsnummer ist oben vor und nach dem Update zitiert und identisch. Ein Rückspielen des Dateistands genügt daher aus Sicht des Schemas. Die beiden Sperrregeln in der Verzeichniskonfigurationsdatei können bleiben; sie verweigern lediglich den Zugriff auf ein Verzeichnis, das auch die Vorversion über ihre eigene Datei sperrt (A7). Beim Rollback ist allerdings zu prüfen, dass die von der Vorversion erwartete Datei im Laufzeitverzeichnis weiterhin vorhanden ist, da sie im Vergleich beider Tags unverändert ausgeliefert wird. Ob ein in der Hauptkonfiguration gesetzter Hostschlüssel von der Vorversion ausgewertet wird, ist nicht bestimmbar — der Schlüssel war dort bisher nicht deklariert, und der Diff belegt nichts über sein Verhalten in 7.0.1; das ist vor einem Rollback in einer Testumgebung zu prüfen (A6). Für die neu hinzugekommene Sperrdatei des Paketmanagers gilt: Sie ist beim Rollback zu entfernen, wenn der Eigenbau wieder gegen die alte Abhängigkeitsauflösung laufen soll (A8).
Plugin-Entwickler
Eigenes JavaScript nach Selektoren auf das Ankerelement der Modal-Bestätigungsschaltfläche durchsuchen und auf den Elementtyp button oder allein auf die Klasse umstellen (A1). Verweise auf die alte Kennung des Bestätigungsdialogtitels und auf h5.modal-title anpassen (A2). Plugins, die den Konfigurationswert für den Vorschaumodus auswerten, gegen den neuen Wert für Aufrufe aus den Themeoptionen prüfen (A3). Wer das CKEditor-Paket selbst registriert oder von ihm abhängt, die Auslieferung aus dem Paketverzeichnis nachvollziehen (A4). Erweiterungen, die das PDF-Asset-Paket verwenden, gegen die neue Hauptversion prüfen (A8).
Theme-Entwickler
Das eigene Administrationstheme gegen die umgestellten Modalfußzeilen prüfen — Regeln auf a.btn-ok greifen nicht mehr (A1). Anschließend die Tab-Auszeichnungen, die neuen fieldset-Elemente in den Massenbearbeitungsformularen, die von h5 auf h2 gewechselten Modaltitel und die neuen Tabellen-caption-Elemente auf Auswirkungen der eigenen Regeln prüfen (A2). Die Vorschau aus den Themeoptionen erneut testen: Sie beendet nun eine laufende Umfragesitzung derselben Umfrage im selben Browser (A3). Wer den Editor in eigenen Theme-Ansichten einbindet, dessen Auslieferungspfad gegenprüfen (A4).
Integratoren
Testautomatisierung, die Modaldialoge über den Linktext der Bestätigungsschaltfläche bedient, auf einen Klassenselektor umstellen — die mitgelieferte Testsuite zeigt das Muster (A1). Weitere Selektoren gegen die umbenannten Kennungen und die geänderte Tab-Auszeichnung prüfen (A2). Auswertungen, die leere Antwortdatensätze aus Vorschauaufrufen bislang herausfiltern mussten, können nach dem Update auf neue Datensätze dieser Art verzichten; bestehende bleiben erhalten (A3). Wenn die eigene Integration LimeSurvey unter einem abweichenden Hostnamen anspricht, diesen in die Hostliste aufnehmen (A6). Bei eigenen Build-Pipelines die neue Sperrdatei berücksichtigen (A8).
API-Nutzer
Die RemoteControl-Schnittstelle selbst ist unverändert. Zu beachten ist lediglich, dass eine gesetzte Hostliste Anfragen mit einem nicht gelisteten Hostnamen laut Kommentar mit Fehler 400 beantwortet; wer die Schnittstelle über einen internen Namen oder eine IP-Adresse anspricht, sollte diesen Eintrag ergänzen (A6).