
PoC: Mass Assignment per Blind-Merge in den Einstellungen von changedetection.io (CVE-2026-71204, Medium 6.3)
Produkt: dgtlmoon/changedetection.io — v0.55.7
Dateien: changedetectionio/blueprint/settings/__init__.py, changedetectionio/forms.py
CWE: CWE-284 — Unsachgemäße Zugriffskontrolle
CVSS 3.1: AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:L — 6.3 (Mittel)
CNA: Turan Security · CVE-Eintrag
Der Speicher-Handler von /settings in changedetection.io erstellt ein Update-Dict aus
form.data['application'] und merged es blind über .update() in die gespeicherten
Anwendungseinstellungen. Da HTML-Kontrollkästchen in übermittelten Formulardaten nur dann
auftauchen, wenn sie aktiviert sind, ist ein manipuliertes POST, das ein
sicherheitsrelevantes Kontrollkästchen-Feld (wie jenes zur Durchsetzung der
API-Schlüssel-Anforderung) einfach weglässt, auf Handler-Ebene nicht von einem Benutzer
unterscheidbar, der es in der Oberfläche abgewählt hat — das blinde .update() schaltet
diese Einstellung stillschweigend ab.
Eine Anfrage, die api_access_token_enabled (oder ein Äquivalent) nie explizit auf
„false“ setzt — sie lässt das Feld einfach aus dem POST-Body weg — führt dazu, dass die
Anwendungseinstellungen mit diesem effektiv deaktivierten Schutz zusammengeführt werden,
ohne einen expliziten Bestätigungsschritt oder ein Audit-Signal, das „Benutzer hat dies
abgewählt“ von „Feld wurde nicht gesendet“ unterscheidet.
/settings-Seite an./settings, bei dem das Feld api_access_token_enabled (oder die jeweilige getestete
geschützte boolesche Einstellung) vollständig aus dem Body weggelassen wird, während
nur nicht zusammenhängende Felder enthalten sind:
POST /settings HTTP/1.1
Content-Type: application/x-www-form-urlencoded
application-some_other_field=value
form.data['application'] → .update()-Zusammenführung im Speicher-Handler
der Einstellungen behandelt das fehlende Feld wie ein explizites „aus“ und deaktiviert
den Schutz stillschweigend, ohne dass der Benutzer (oder ein Prüfer, der die Anfrage
prüft) ein explizites Ausschaltsignal sieht.Die Verwendung eines blinden Dict-.update() aus rohen Formulardaten vermischt für
kontrollkästchengestützte Einstellungen „Feld fehlt im POST“ mit „Feld wurde explizit auf
false gesetzt“ — HTML-Formulare übermitteln nicht aktivierte Kontrollkästchen nie, daher
ist dieses Muster für jedes Einstellungsfeld mit Sicherheitsauswirkungen unsicher.
Zähle die erwarteten booleschen Einstellungsfelder explizit auf und weise fehlenden
Feldern standardmäßig ihren aktuell gespeicherten Wert zu (nicht False), oder verwende
eine Formularbibliothek, die „nicht übermittelt“ von „als deaktiviert übermittelt“
unterscheidet und sicherheitsrelevante Umschalter explizit validiert, anstatt sie per
blindem Dict-Merge zu übernehmen.