Media

ApostropheCMS uploadfs con backend Azure filtra el token SAS en cada URL pública de adjuntos

  • Publicada: 20.10.2026
  • Actualizado: 20.10.2026 21:30

Resumen

Cuando uploadfs se configura con el backend de Azure y sas: true (una configuración compatible introducida en uploadfs 1.25.0), createContainer() construye el BlobServiceClient a partir de una URL que incrusta la cadena de consulta (query string) SAS completa, y los clientes derivados del SDK v12 de Azure heredan dicha cadena de consulta. Como resultado, getUrl() devuelve una URL base que incluye la firma SAS completa de la cuenta/contenedor (?sv=...&sig=...), y attachment.url() de Apostrophe la antepone a cada enlace público de archivos adjuntos, exponiendo una credencial SAS a nivel de contenedor (comúnmente sp=rwdlac, acceso total de lectura/escritura/eliminación/listado) a todos los visitantes del sitio, incluidos los anónimos. Cualquiera que pueda ver la URL de un adjunto puede leer, sobrescribir, eliminar y listar todos los blobs del contenedor durante la vigencia del token SAS. Un error funcional complementario (la ruta del blob se añade después de la cadena de consulta, generando URLs corruptas) evidencia que esta ruta de código nunca se ejecutó de extremo a extremo. El modo de clave compartida (predeterminado) y los backends que no son de Azure no están afectados.

Verificado en el commit 5a3746aaed49761e171c2cbfe793267c959829fd (uploadfs 1.27.0 en el monorepositorio de apostrophe).

Detalles

Causa raíz: se reutiliza una URL de cliente que contiene credenciales como la URL base pública. La cadena:

  • Cliente con credenciales incrustadas: azure.js#L123-L125 — new BlobServiceClient("https://<account>.blob.core.windows.net?<SAS query string>") donde cluster.key es la cadena SAS completa que incluye sig
  • Punto de filtración: azure.js#L513-L520 — getUrl() toma getContainerClient(...).getBlobClient('').url como baseUrl; los clientes derivados de SDK v12 heredan la cadena de consulta SAS, por lo que baseUrl ya contiene ?sv=...&sig=...
  • Exposición pública: attachment/index.js#L694 — attachment.url() = uploadfs.getUrl() + path para cada enlace de archivo adjunto renderizado; attachment/index.js#L1503 — getBrowserData() también envía uploadsUrl a cada sesión de edición iniciada
  • Error complementario: la ruta del blob se agrega después de la cadena de consulta (/container/?sv=...&sig=XXX/attachments/id-name), por lo que estas URLs también quedan rotas, lo que prueba que la ruta de código 1.25.0 nunca se probó

Superficie de ataque: toda página pública que renderice URLs de archivos adjuntos (imágenes, enlaces de descarga), además de la uploadsUrl entregada a las sesiones de los editores. La fuga es pasiva e incondicional: no se requiere ninguna acción por parte de la víctima más allá de servir una página. La credencial se propaga adicionalmente a través del código fuente HTML, registros, cabeceras Referer y registros de acceso de proxies o CDN.

Mitigación sugerida:

  1. Eliminar la cadena de consulta antes de construir URLs públicas: const u = new URL(blob.svc.getContainerClient(...).getBlobClient('').url); u.search = ''; (o componer accountUrl + '/' + container manualmente) y añadir la ruta del blob al pathname, no después de la consulta.
  2. Documentar que el modo SAS debe utilizar el privilegio mínimo (solo lectura, idealmente sr=b por blob), y priorizar la generación de URLs firmadas de solo lectura y de corta duración por blob a través de generateBlobSASQueryParameters en lugar de incrustar un SAS a nivel de servicio en URLs públicas permanentes.

PoC

PoC completo publicado como el primer comentario abajo (poc.js + README; sin conexión, no se requiere cuenta de Azure). Replica con exactitud los dos pasos de la biblioteca con la dependencia declarada @azure/storage-blob@12:

  1. npm install @azure/storage-blob@12 && node poc.js
  2. El script construye new BlobServiceClient("https://myaccount.blob.core.windows.net?sv=...&sig=FAKESIGNATURE") exactamente como createContainer(), luego evalúa la lógica de getUrl() (getContainerClient('uploads-container').getBlobClient('').url) y valida que la URL base resultante todavía contiene el parámetro sig.
  3. Salida observada (código de salida 0):
baseUrl: https://myaccount.blob.core.windows.net/uploads-container/?sv=2021-06-08&ss=b&srt=co&sp=rwdlac&se=2099-01-01&sig=FAKESIGNATURE
attachment URL as served to visitors: https://myaccount.blob.core.windows.net/uploads-container/?sv=2021-06-08&ss=b&srt=co&sp=rwdlac&se=2099-01-01&sig=FAKESIGNATURE/attachments/abc123-photo.jpg

La URL generada filtra el token (sv…sig) y evidencia la ubicación errónea de la ruta. La comprobación cruzada de attachment/index.js confirma que esta URL llega intacta a las páginas públicas.

Impacto

  • Qué es: credenciales insuficientemente protegidas (CWE-522) que dan lugar a exposición de información (CWE-200). Un token SAS a nivel de contenedor —al cual se le suele otorgar permisos de sp=rwdlac (lectura/escritura/eliminación/listado/ACL)— queda expuesto a cualquier visitante del sitio, incluidos usuarios anónimos, con validez durante toda la vigencia del SAS (a menudo años). Quienes posean el token pueden leer, sobrescribir, eliminar y enumerar todos los archivos adjuntos en el contenedor; la biblioteca no aplica ninguna restricción.
  • A quién afecta: sitios Apostrophe que utilizan uploadfs con el backend de Azure y sas: true (introducido en 1.25.0; presente hasta 1.27.0). El modo predeterminado de clave compartida y otros backends no se ven afectados. Cuando el token SAS se aprovisiona únicamente con permisos de lectura, el impacto se reduce a la lectura o descarga no autenticada de todos los archivos adjuntos.

Reportado por Kimi Security Team (bug-report@moonshot.ai).

Qué hacer

Actualice a uploadfs versión 1.28.0 o posterior.

Software afectado

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

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm uploadfs >= 1.25.0, < 1.28.0 1.28.0

Referencias

Puntuación CVSS 5.6/10
Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L
Debilidad (CWE)
CWE-200, CWE-522
Plataforma
npm
Paquete
uploadfs
Publicada
20.10.2026
Actualizado
20.10.2026 21:30

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

OSV / GitHub Advisory Database - GHSA-hhph-8536-gfq5 - CC BY 4.0

Historial de vulnerabilidades: uploadfs

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.

Esta es la única vulnerabilidad conocida de este paquete.

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.