Skip to content

owncloud.online 11.0.25 - #114

Merged
BWTECH-github merged 11 commits into
mainfrom
release-11.0.25
Oct 28, 2026
Merged

BWTECH-github merged 11 commits into
mainfrom
release-11.0.25

Conversation

@BWTECH-github

Copy link
Copy Markdown
Owner

owncloud.online 11.0.25 – übernommen aus dem Entwicklungsstand (Picks mit gleicher Patch-ID), ohne die Erinnerungen.

Merge nur per Fast-Forward (git push origin release-11.0.25:main), nicht über die GitHub-Oberfläche. Der Tag v11.0.25 kommt auf den Kopf dieses Zweigs.

Inhalt

  • Security: access_token, requesttoken und password werden in der protokollierten Adresse maskiert (Protokollarten owncloud und syslog). Voraussetzung für oco_office 0.4.2 aus dem Marktplatz.
  • Security: Widerruf eines App-Passworts bzw. einer OAuth2-Freigabe und „Sitzung entfernen“ beenden die Sitzung eines Sync-Clients. Ein Kennwortwechsel beendet die Sitzungen von Clients, die sich mit dem Kennwort anmelden, spätestens nach last_check_timeout.
  • Enhancement: Files_Versions\Storage::skipNextVersion() – Apps können die Version des nächsten Schreibvorgangs auslassen.
  • Bugfix: Markt-App ist direkt nach der Neuinstallation eingeschaltet.
  • Bugfix: Anmeldung ohne Benutzer- oder Kennwortfeld bzw. mit Arrays erzeugt keine PHP-Deprecation mehr.
  • Bugfix: Fehler vor dem Versand der Reset-Mail blockiert die nächste Anforderung nicht mehr.
  • Bugfix: owncloud.online statt alter Produktnamen in den Übersetzungen.
  • Doku: neuer Abschnitt „Gerät verloren oder Zugangsdaten abgegriffen“ in docs/administration/troubleshooting.md.

Lokal geprüft

  • PHPUnit (SQLite): 1374 Tests ohne Fehler; php -l, php-cs-fixer, mkdocs build --strict
  • Update 11.0.24 → 11.0.25 wie beim Kunden: erfolgreich, keine App aus- oder eingeschaltet, keine Migrationen
  • oco_office 0.4.2 (unverändertes Paket): 87/87 Ende-zu-Ende-Prüfungen, keine Tokens im Klartext im Protokoll
  • Sitzungen Ende-zu-Ende (Browser, WebDAV, owncloudcmd): 40/41 (eine falsche Testerwartung), Kennwort vergessen 10/10, Anmeldeformular 6/6, Neuinstallation 4/4

Bekannte Einschränkungen

  • Ein Kennwortwechsel sperrt niemanden verlässlich aus, der eine Sitzung hält. Vorgehen laut Doku: Kennwort ändern, alle übrigen Sitzungen entfernen, App-Passwörter und OAuth2-Freigaben widerrufen.
  • Maskiert wird nur der Abfrageteil der Adresse; Tokens im Pfad sowie Meldungs- und Exception-Texte bleiben unverändert.
  • Direkt nach dem Update prüft der Server alte Client-Sitzungen: Einträge „Login failed“ und die Bremse hinter gemeinsamen Adressen (NAT) sind möglich.

Vor dem Merge

  • CI grün auf allen Datenbanken (besonders SessionTest und DefaultTokenMapperTest) und im Update-Test ab 11.0.23/11.0.24
  • Plugin-Verträglichkeit: alle Marktplatz-Apps, gleiche Prüfungen auf 11.0.24 und nach dem Update auf 11.0.25 (läuft)

…Texten

In core/l10n und apps/*/l10n standen in 68 Texten noch Schreibvarianten
des alten Produktnamens – Tippfehler, Großschreibung, Hashtag, kyrillische
Umschrift. Alle nennen jetzt owncloud.online, jeweils gleich in .json und
.js (90 Dateien, Gegenprobe: .json und .js je Sprache wieder deckungsgleich).

Kern (core/l10n):
- de, de_AT, de_CH, de_DE: Einzelbenutzermodus „ownClound-Instanz“ →
  „owncloud.online-Instanz“
- eu: Teilen-Hinweis „ownClud-en“ → „owncloud.online-en“
- mk: Reverse-Proxy-Hinweis „OwnCloud“ → „owncloud.online“
- sl: Hinweis ohne Internetverbindung „OwnCloud“ → „owncloud.online“
- sr: Weiterleitung nach dem Update und Einzelbenutzermodus „оунКлауд“ →
  „owncloud.online“
- sv: Reverse-Proxy-Hinweis dreimal „Owncloud“ → „owncloud.online“

federatedfilesharing:
- es, ja („OwnCloud“), sv („Owncloud“): „Share with me via …“ →
  „owncloud.online“
- fr, oc: „Share with me through my Federated Cloud ID“ mit und ohne
  „, see %s“: „#owncloud“ → „#owncloud.online“; sv dasselbe mit „, see %s“

federation:
- es „Trusted Servers“ und eu Beschreibung: „onwCloud“ → „owncloud.online“
- es_AR: „No server found“, Beschreibung (zweimal), „Trusted Servers“,
  „+ Add server“, „Server“: „OwnCloud“ → „owncloud.online“
- es_MX Beschreibung, pt_BR „Trusted Servers“, fr „Server“: „OwnCloud“ →
  „owncloud.online“
- fr, oc „+ Add server“: „Owncloud“ → „owncloud.online“
- ru, ru_RU „Server added to the list of trusted servers“: „ownClowd“ →
  „owncloud.online“
- sr, sr@latin: „Server added …“, „No server found“, Beschreibung
  (zweimal), „Trusted Servers“, „+ Add server“, „Server“: „оунКлауд“ →
  „owncloud.online“

files_external:
- es, ru, ru_RU, ug „Couldn't get the information from the remote server“:
  „OwnCloud“ → „owncloud.online“
- sr „SMB / CIFS using OC login“: „оунКлауд“ → „owncloud.online“

files_sharing:
- de, de_CH, de_DE „No compatible server installation found at {remote}“:
  „OwnCloud-Installation (7 oder höher)“ → „owncloud.online-Installation“
- pt_PT „instalação OwnCloud (7 ou superior)“ → „instalação
  owncloud.online“, sv „OwnCloud Installation (7 eller senare)“ →
  „owncloud.online-installation“, sr „оунКлауд инсталације верзије 7 или
  више“ → „owncloud.online инсталације“, uk „OwnCloud (7 або вище)“ →
  „owncloud.online“. Die Versionsangabe gehört zum alten Produkt und steht
  nicht im Quelltext, sie entfällt.
- „Invalid server url“: de, de_CH „OwnCloud-URL“ → „owncloud.online-URL“,
  de_DE „OwnCloud-Adresse“ → „owncloud.online-Adresse“, es_AR „OwnCloud“,
  nn_NO „ownClud“, sr „оунКлауд“ → „owncloud.online“

updatenotification:
- da, uk Hinweis zum Update-Kanal: „OwnCloud“ → „owncloud.online“
- es_AR „owncloud.online core“: „núcleo wnCloud“ → „núcleo de
  owncloud.online“
- pt_BR, pt_PT Enterprise-Hinweis: „uma edição OwnCloud Enterprise“ → „uma
  edição Enterprise“ – der Quelltext nennt dort kein Produkt
- ug Enterprise-Hinweis: „ئۆزىڭىزنىڭ Cloud“ (wörtlich „Ihr eigenes
  Cloud“) → „ئۆزىڭىزنىڭ“, zweimal

Unverändert bleiben Beispielpfade wie username@example.com/owncloud (auch
gl „…/ouwncloud“), Platzhalter und technische Bezeichner.

Test: ProductNameTranslationTest liest alle .json und .js unter core/l10n
und apps/*/l10n und sucht die Schreibvarianten (nicht nach „/“, nicht vor
„.online“). Vorher 136 Fundstellen (68 Texte in je zwei Dateien), danach
keine.
…eisen

LoginController::arrayAsMissing() macht aus user[]=x – wie aus einem
fehlenden Feld – null. tryLogin() reicht das über Session::login() an
Manager::checkPassword() weiter, und dort stand
str_replace("\0", '', null): seit PHP 8.1 „Passing null to parameter #3
($subject)“, einmal für den Namen, einmal für das Passwort.

checkPassword() behandelt null jetzt als leeres Feld ((string)); für
Zeichenketten ändert sich nichts, Bremse und Backends bekommen '' wie bei
einem leer abgeschickten Feld. Ein Array als Name oder Passwort – das kann
über andere Aufrufer wie checkPerson (OCS) oder den Token-Endpunkt noch
ankommen – endet sofort mit false. Bisher lief es bis in die
Brute-Force-Bremse („Array to string conversion“ im Doctrine-Treiber) und
in die Backends.

Test: ManagerTest::testCheckPasswordTreatsMissingFieldsAsEmpty fängt
E_DEPRECATED selbst ab (phpunit-autotest.xml blendet Deprecations aus):
vorher zwei Meldungen aus str_replace(), danach keine; das Backend bekommt
''. testCheckPasswordRejectsArrays: vorher erreichte das Array
Database::checkPassword(), jetzt nicht mehr.
LostController::sendEmail() speicherte den Token vor dem Zusammenstellen
der Mail. Der Fehlerzweig aus 4465e99dbd, der ihn bei gescheitertem
Versand wieder entfernt, lag nur um createMessage() … send(). Scheiterte
vorher etwas – Vorlagen (OC_Template::fetchPage()), Anzeigename des
Empfängers –, blieb der Token stehen: Fünf Minuten lang galt jede neue
Anforderung als „recently sent“, verschickte nichts und meldete trotzdem
Erfolg.

Jetzt schreibt sendEmail() den Token im try unmittelbar vor
mailer->send(). Scheitert vorher etwas, bleibt der Stand von vor der
Anforderung erhalten – ein älterer, noch gültiger Link wird dann auch
nicht entwertet. Der catch entfernt nur einen Token, den diese Anforderung
selbst gespeichert hat; scheitert send(), bleibt es beim Verhalten aus
4465e99dbd. Fehlermeldungen und die Fünf-Minuten-Sperre nach einer
zugestellten Mail sind unverändert.

Test: LostControllerTest::testFailureBeforeSendingLeavesNoRecentlySentToken
lässt das Zusammenstellen beim ersten Versuch scheitern (Anzeigename wirft)
und fordert eine Minute später erneut an. Vorher stand danach
„12000:FirstToken“, der zweite Versuch verschickte nichts; jetzt ist kein
Token gespeichert und der zweite Versuch verschickt die Mail.
Setup::install() rief Installer::installShippedApps() auf, bevor
apps_paths mit apps-external in config.php stand. \OC::$APPSROOTS entsteht
beim Start des Prozesses aus apps_paths, bei einer Neuinstallation also nur
aus apps/. installShippedApps() fand die Markt-App (apps-external/market,
default_enable) deshalb nicht: Sie blieb nach occ maintenance:install und
nach dem Web-Installer aus, bis occ upgrade sie beim ersten Update
nachholte. docs/installation/linux-server.md §10 („wird bei der
Installation aktiviert“) stimmte damit nicht.

Entscheidung: Reihenfolge korrigieren statt die Doku zurückzunehmen. Der
Eintrag ist derselbe wie bisher und wie bisher nur, wenn apps_paths fehlt;
er steht jetzt vor installShippedApps() (Setup::addDefaultAppsPaths()).
Vorhandene Verzeichnisse, die der laufende Prozess noch nicht kennt, kommen
zusätzlich in \OC::$APPSROOTS. Die Markt-App bringt weder Tabellen noch
install.php mit; installiert wird genau das, was occ upgrade bisher beim
ersten Update nachholte, nur früher. Bestehende Installationen, Updates und
vorgegebene apps_paths ändern sich nicht. In der CI ist die Markt-App nach
der Installation damit ebenfalls an; tests/apps.php lädt nur Tests aus
apps/.

Tests: SetupTest::testAddDefaultAppsPaths* (eigenes Serververzeichnis,
drei Fälle). Nach dem Herauslösen der Methode ohne Verhaltensänderung rot
(\OC::$APPSROOTS ohne apps-external), danach grün. Probe mit frischer
occ maintenance:install (sqlite) in einer eigenen WSL-Kopie: vorher
„market enabled“ leer, danach „yes“, installed_version 0.10.10,
CheckUpdateBackgroundJob eingetragen, Log ohne Fehler. App-, Installer-
und Repair\Apps-Tests laufen mit aktiver Markt-App grün.
Sync-Clients schicken mit jeder Anfrage ihr Sitzungs-Cookie mit. Nach dem
Widerruf eines App-Passworts in den Einstellungen synchronisierte ein
solcher Client unbegrenzt weiter: widerrufenes App-Passwort + Cookie 207,
nur Cookie 207 (belegt an 11.0.40 und dev-503-sitzung). Sitzungen, die ein
Client selbst angemeldet hat (Vermerk AUTHENTICATED_TO_DAV_BACKEND), prüfte
OC_App::loadApps() nie gegen die Anmeldung, mit der sie begannen; fehlte
ihr Sitzungstoken, legte es dasselbe einfach neu an. Darum wirkte auch
„Sitzung entfernen“ unter „Sitzungen“ nicht, und nach dem Widerruf einer
Desktop-Freigabe (OAuth2) galt die Sitzung mit dem Cookie allein weiter,
auch für die Weboberfläche. Jede Anfrage verlängerte sie. owncloud/core
master verhält sich gleich (loadApps, validateSession, TokenAuthModule).

Session::validateDavSession() prüft solche Sitzungen jetzt vor jeder
Anfrage, wie validateSession() die des Browsers:

- App-Passwort ('app_password' in der Sitzung): Das Token muss bestehen
  und dem Nutzer gehören, sonst endet die Sitzung – auch bei Anfragen nur
  mit Cookie.
- Sitzungstoken: Hatte die Sitzung schon eines (neuer Vermerk
  session_token_created aus createSessionToken()), muss es bestehen.
  Fehlt es noch, entsteht es wie bisher erst mit der zweiten Anfrage,
  damit Clients ohne Cookies nicht je Anfrage ein Token anlegen. Die
  letzte Aktivität des Tokens wird höchstens einmal je Minute
  fortgeschrieben; sonst löschte der Aufräumjob die Tokens laufender
  Sitzungen nach session_lifetime.
- Anmeldemodul (OAuth2, OpenID Connect): tryAuthModuleLogin() merkt sich
  Modul und SHA-256 des Authorization-Kopfs. Einen anderen Kopf – auch
  keinen, also nur das Cookie – prüft das Modul sofort, denselben nach
  core/last_check_timeout Minuten (last_check am Sitzungstoken, wie die
  Kennwortprüfung). Bestätigt es den Nutzer der Sitzung nicht, endet sie.
- Sitzungen von vor dieser Änderung: Ihr Token bekommt den Vermerk mit
  der ersten Anfrage. Schicken sie einen Bearer, wird das Modul vermerkt,
  das ihren Nutzer bestätigt; schicken sie ohne App-Passwort nur das
  Cookie, melden sie sich einmal neu an.

Eine beendete Sitzung wird abgemeldet und verworfen (Sitzungstoken
gelöscht, Sitzung geleert); das Protokoll meldet auf Stufe info „Client
session of <konto> ended: <Grund>“. Browser-Sitzungen laufen unverändert
über validateSession().

Bewusst nicht sofort verworfen wird eine OAuth2-Sitzung bei der ersten
WebDAV-Anfrage mit widerrufenem Bearer: Ein abgelaufenes Access-Token
sieht der Kern genauso, und dann risse jedes stündliche Ablaufen die
Sitzung ab (Neuanmeldung je Client und Stunde, bei parallelen Anfragen
genau die Last, die dev-503-sitzung entschärft). Die Anfrage selbst weist
die OAuth2-App wie bisher sofort ab (401); OCS und Weboberfläche prüfen
den Kopf ebenfalls bei jeder Anfrage und verwerfen die Sitzung dabei.
Mit nur dem Cookie endet sie sofort, sonst nach core/last_check_timeout.

Je Anfrage liest das wie bisher das Sitzungstoken aus der Datenbank, bei
App-Passwörtern dazu dessen Token, das die Basic-Anmeldung derselben
Anfrage ohnehin lädt (gemerkt im Provider). Geschrieben wird nur bei
Änderungen. TokenAuthModule, BasicAuthModule und das DAV-Backend bleiben
unverändert: Bei geprüfter Sitzung bestätigt der Rückgriff des
TokenAuthModule auf das Sitzungstoken nur noch deren eigenen Nutzer.

Tests: SessionTest deckt App-Passwort (gültig, widerrufen, fremd),
Sitzungstoken (entfernt, erst anlegen, vorhanden, parallel angelegt,
fremd), gesperrten Nutzer, Kennwort-Sitzung, Anmeldemodul (gleicher Kopf,
nach Rewrite, nur Cookie, Basic, erneuert, fremder Nutzer, Frist fällig
und gerade nicht, widerrufen, Modul weg), Sitzungen von vor der Änderung
und den Vermerk in tryAuthModuleLogin() ab. Ohne die Änderung scheitern
alle 29 neuen Tests, mit ihr sind alle 82 grün; 27 Mutationen der Regeln,
alle erkannt. Volle Suite: dieselben 44 umgebungsbedingten Fehler
(Vorschau) wie dev-503-sitzung, keine neuen. php-cs-fixer, phpstan und
phan ohne Befund.

Nachgestellt an einer eigenen Instanz (11.0.40 + dev-503-sitzung, Redis
mit Sitzungssperre wie testoo, oauth2 0.10.0), vorher → nachher:
- App-Passwort widerrufen: App-Passwort + Cookie 207 → 401, nur Cookie
  207 → 401; Sitzung und Sitzungstoken gelöscht
- Desktop-Freigabe widerrufen: Bearer + Cookie 401 → 401, nur Cookie
  207 → 401
- Sitzung unter „Sitzungen“ entfernt (App-Passwort, Bearer, Kennwort):
  nur Cookie 207 → 401 (vorher legte die Anfrage das Token neu an); mit
  gültiger Anmeldung wieder 207
- Weboberfläche mit dem Cookie: nach Widerruf des App-Passworts
  200 → 401, OAuth2-Sitzung nur mit Cookie 200 → 401
- nur Cookie zu einer OAuth2-Sitzung ohne Widerruf: 207 → 401 (gewollt;
  Desktop- und Android-Client senden den Bearer mit jeder Anfrage)
- erneuertes Access-Token mit altem Cookie: 207, Sitzung bleibt
- OCS mit widerrufenem Bearer: wie bisher 401
- 20 parallele PROPFIND (Bearer, App-Passwort, Kennwort), auch mit Redis
  +1,2 ms: alle 207, kein 503, Laufzeiten wie dev-503-sitzung (Bearer
  p50 0,61 s und p95 0,83 s in beiden Ständen, App-Passwort p95
  0,90 → 0,91 s, Kennwort p95 1,29 → 1,28 s)
- Playwright: Anmeldung, Weboberfläche, öffentlicher Link, Gast
  unverändert grün
Nachbesserung zu cb5c6e3081. Desktop 6.0.3 schickt die Token-Erneuerung
(POST /index.php/apps/oauth2/api/v1/token, Client-Daten über HTTP-Basic)
über die Kontoverbindung samt Sitzungs-Cookie. validateDavSession() sah
dort einen anderen Authorization-Kopf als den bestätigten Bearer, das
OAuth2-Modul antwortete für Basic ohne Nutzer, und die Sitzung endete.
Jede Erneuerung kostete so die Sitzung: Die nächsten 20 parallelen
PROPFIND meldeten sich alle neu an. Ebenso endete sie mit einem
abgelaufenen Access-Token zur fälligen Prüfung, mit dem alten Token, das
nach der Erneuerung noch unterwegs war, am Token-Endpunkt mit
Client-Daten im Formular und an der OpenID-Connect-Discovery
(/apps/openidconnect/config, Ziel von /.well-known/openid-configuration).

- Token-Endpunkt (POST) und Discovery (GET) lassen die Sitzung unberührt:
  kein Vermerk, keine Aktivität, gleich mit welchem Authorization-Kopf.
  Verglichen werden Pfad (getRawPathInfo()) und Methode wie in
  BasicAuthModule.
- Lehnt das Anmeldemodul einen Bearer mit einer Ausnahme ab (abgelaufen
  oder widerrufen, für den Kern nicht zu unterscheiden), lässt die Prüfung
  die Sitzung für das erneuerte Token bestehen. Die Anfrage selbst weisen
  WebDAV (Bearer-Backend des Moduls) sowie OCS und Weboberfläche
  (verifyAuthHeaders(), beendet die Sitzung dabei wie bisher) ohnehin mit
  401 ab. Ohne Bearer, mit dem Bearer eines anderen Nutzers, ohne Modul
  oder wenn das Modul ohne Nutzer antwortet, endet sie wie bisher: Ohne
  Nutzer bürgt das Modul nicht für den Kopf, und verifyAuthHeaders() ließe
  die Anfrage über das Sitzungstoken durch.

Der Vorschlag der Prüfung, nur bei Ausnahme zu beenden und bei null
nicht, hätte bei oauth2 0.10.0 nicht gegriffen: Für abgelaufene Tokens
wirft dessen AuthModule (LoginException „Invalid token“). Ohne Nutzer
antwortet es nur ohne Bearer und für unbekannte Tokens, wenn die App
openidconnect eingeschaltet ist.

Kennwortwechsel (zweiter Befund, bestand schon vorher): Client-Sitzungen
ohne Anmeldemodul prüfen jetzt alle core/last_check_timeout Minuten das
hinterlegte Kennwort, wie Browser-Sitzungen und wie eine Anmeldung mit
denselben Zugangsdaten:
- App-Passwort: das Kennwort, mit dem es angelegt wurde. Gilt es nicht
  mehr, wird das App-Passwort ungültig und die Sitzung endet, wie bisher
  bei einer Anmeldung damit; Konten aus LDAP ausgenommen, wie dort.
- Kennwort-Sitzung nur mit Cookie: das bei der Anmeldung hinterlegte
  Kennwort. Mit Kennwort im Kopf prüft wie bisher BasicAuthModule.
Von parallelen Anfragen mit demselben Token prüft nur eine:
IProvider::claimCredentialCheck() schreibt last_check mit einem bedingten
UPDATE (DefaultTokenMapper::claimLastCheck()). Lässt sich das Kennwort
nicht prüfen (Token ohne Kennwort, Ausnahme der Benutzerverwaltung),
bleibt die Sitzung bis zur nächsten Prüfung. Log ersetzt in Stacktraces
die Parameter der neuen Methoden, die App-Passwort oder Sitzungskennung
tragen. Changelog und troubleshooting.md beschreiben das Verhalten jetzt,
wie es ist, auch die Bremse: Prüfungen mit veraltetem Kennwort zählen als
Fehlversuch.

Tests: SessionTest (Token-Endpunkt mit Basic und Formular, Discovery,
GET am Token-Pfad, anderer Präfix, abgelehnter alter und fälliger
Bearer, Modul ohne Nutzer, Fristgrenze, Kennwortprüfung für App-Passwort
und Kennwort-Sitzung samt LDAP, Token ohne Kennwort, Ausfall der
Benutzerverwaltung, parallele Übernahme), DefaultTokenProviderTest,
DefaultTokenMapperTest (Datenbank) und LoggerTest. Ohne die Änderung
scheitern die neuen Tests (SessionTest 18, Provider 3, Mapper 2,
Logger 27), mit ihr sind alle grün; 20 Mutationen der Regeln, alle
erkannt. Volle Suite: dieselben 44 umgebungsbedingten Fehler (Vorschau)
wie zuvor, keine neuen. php-cs-fixer und phan ohne Befund, phpstan ohne
Befund in den geänderten Dateien.

Nachgestellt an einer eigenen Instanz (11.0.40 + Zweig, MariaDB, Redis
mit Sitzungssperre wie testoo, oauth2 0.10.0), vorher → nachher:
- Erneuerung mit Cookie (Basic, Formular), Discovery mit Cookie: Sitzung
  beendet → bleibt
- abgelaufenes Token, Prüfung fällig: 401, Sitzung beendet → 401, bleibt;
  alter Bearer nach der Erneuerung: beendet, eine Vollanmeldung → bleibt;
  ungültiger Bearer + Cookie an WebDAV: 401, beendet → 401, bleibt (OCS
  401 und beendet wie vorher)
- Erneuerung, dann 20 parallel: je Runde 20 Vollanmeldungen, p50
  0,50–0,53 s, max 0,99–1,08 s → keine, p50 87–104 ms, max 186–216 ms
  (dev-503-sitzung 64–85 ms, max 110–199 ms). 7–11 Antworten schicken
  dieselbe Sitzungskennung noch einmal (zweites session_start() beim
  Schreiben des neuen Fingerabdrucks), keine neue.
- Kennwortwechsel, Prüfung fällig: Kennwort-Sitzung nur Cookie 207 → 401,
  App-Passwort + Cookie und nur Cookie 207 → 401, App-Passwort gelöscht
- 20 parallel bei fälliger Prüfung nach Kennwortwechsel: eine Prüfung
  („Login failed“ 1, dazu 1 der abgewiesenen Neuanmeldung), 19 × 207,
  1 × 401; mit gültigem Kennwort 20 × 207, p50 81 ms
- unverändert: fremder Bearer, Widerruf von App-Passwort und
  Desktop-Freigabe (auch parallel), entfernte Sitzung, nur Cookie zu
  einer OAuth2-Sitzung 401, OCS, Gast, Browser; Bursts mit Bearer,
  App-Passwort und Kennwort wie dev-503-sitzung (p50 70–76 ms, p95
  135–136 ms)
- Playwright: Anmeldung, Weboberfläche, öffentlicher Link, Gast grün
…skipNextVersion)

Editoren mit automatischem Zwischenspeichern (oco_office: Autosave von
Collabora) erzeugten bei jedem Zwischenspeichern eine Version. Neue
Methode Storage::skipNextVersion($path): der nächste Schreibvorgang auf
den Pfad legt keine Version an – einmalig und nur in dieser Anfrage.
Test testSkipNextVersion.
…ten Adresse maskieren

Der Kern schreibt die Anfrage-Adresse in jeden Protokolleintrag. Collabora
hängt das WOPI-Zugriffstoken als access_token an jede Anfrage – jeder
Eintrag während eines WOPI-Aufrufs hätte das Token im Klartext enthalten.
Owncloud::sanitizeUrl() maskiert die Werte, Datei- und Syslog-Protokoll
nutzen sie.
f4c475a (access_token, requesttoken und password in der protokollierten
Adresse maskieren) und a6b9cbc (Storage::skipNextVersion) kamen ohne
Fragment unter changelog/unreleased. log-url-secrets-masked (Security)
nennt auch die Grenzen der Maskierung, versions-skip-next-version
(Enhancement) die neue Methode. Die übrigen Änderungen für 11.0.25 bringen
ihr Fragment mit.
…ch aus

Doku, CHANGELOG und Changelog-Fragment zu „Widerruf und Kennwortwechsel
beenden die Sitzung eines Sync-Clients“ versprachen mehr, als der Code
hält. Ein Kennwortwechsel beendet die Sitzungen von Clients, die sich
regulär mit dem Kennwort anmelden, sperrt aber niemanden verlässlich
aus, der eine Sitzung hält: Sitzungen und App-Passwörter ohne
hinterlegtes Kennwort überstehen ihn, und Anfragen mit HTTP-Basic-Kopf
überlässt die neue Prüfung der Anmeldung mit HTTP-Basic.

- troubleshooting.md: Einschränkungen beim Kennwortwechsel benannt,
  neuer Abschnitt „Gerät verloren oder Zugangsdaten abgegriffen“ mit
  dem Vorgehen (Kennwort ändern, übrige Sitzungen entfernen,
  App-Passwörter und OAuth2-Freigaben widerrufen, bei Bedarf Konto
  deaktivieren). „Oder das Kennwort ändern“ als gleichwertiges Mittel
  entfernt.
- CHANGELOG.md 11.0.25: Aussage zu App-Passwörtern nach einem
  Kennwortwechsel eingeschränkt, bekannte Einschränkung erweitert.
- changelog/unreleased/revoke-ends-client-sessions: Typ Security wie im
  CHANGELOG, Satz zu HTTP-Basic korrigiert, Einschränkungen und Bremse
  gegen Passwort-Raten ergänzt.

Keine Code-Änderung.
@BWTECH-github
BWTECH-github merged commit 658f978 into main Oct 28, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant