| CVE | Icon | Vulnerability name | Date | Responsible Security Disclosure by | Stars | Process | Vulnerabilities |
|---|---|---|---|---|---|---|---|
| - | CacheBleed | 2026-10-02 | alham-rizvi | Reported privately by alham-rizvi through GitHub Security Advisory GHSA-w3qg-pf27-g68r, with details, a proof of concept and a suggested fix; validated and fixed by xet7. | Attachments were answered with Validation found the same header in both download branches and both avatar routes, and Meteor-Files' own Every file response, its 304 and the thumbnail are now CWE-524, CWE-525. Medium severity (CVSS 5.9). No CVE assigned. Affected v8.16 through v12.14. Fix prepared locally for the Upcoming release; not yet released. |
Advisory GHSA-w3qg-pf27-g68r reported that WeKan authorized an attachment download against the board and then marked the response public for a year. public explicitly allows a shared cache to store a response produced for an authenticated request, and with no Vary on the credential the cache key is only the URL. A later request for that URL, with no cookie and no token, is answered from the cache without reaching WeKan. The report showed this with WeKan's own header function and an RFC 9111 cache implementation, and gave the nginx setup for an end-to-end check.
Reading the source confirmed the three places the report named and found three more: both avatar routes, and Meteor-Files' own /cdn/storage/attachments/<id>/original/<name> route, which is guarded by WeKan's access callback but sent the library's default public, max-age=31536000, s-maxage=31536000. The header came in with the universal file server in v8.16. Attachment IDs are random, so the URL has to be known: a user later removed from the board, proxy or access logs, browser history, chat or Referer data.
One helper sets the policy for every response that carries a stored file: Cache-Control: private, no-cache keeps it out of every shared cache and makes the browser revalidate before each use, so the access check runs again and a revocation takes effect at once. Vary: Cookie, Authorization, X-Auth-Token names the credentials for any cache that ignores private. The 304 for a revalidation and the thumbnail carry the same headers, and both file collections pass the same value to Meteor-Files. The suggested fix kept a public, one-year cache for public boards; the fix does not, because a board can be made private later and a copy cached as public would outlive that change. The ETag keeps revalidation a bodiless 304.
None. The fix changes the headers of responses that were authorized, and nothing is refused. The attack happens in a shared cache that WeKan never sees, so there is no attempt to record in Admin Panel → Problems.
A unit test drives the policy against the shared-cache rules the report used: the old headers are stored and reused for an anonymous request, the new ones are neither. It checks each file route, the 304 and the thumbnail. A tree-wide negative test fails on any public Cache-Control value, any file collection left on the Meteor-Files default, and any file route that sends an ETag without the policy. A Playwright test checks the headers on the original, the download, the thumbnail and Meteor-Files' route, and that a signed-out request for a private board's file is refused. The browser test and an end-to-end run behind a caching proxy were not run where the fix was written.
Source fix and regression tests
API answers now carry Cache-Control: no-store unless a route sets its own, and the legacy attachments route answers only GET and HEAD, with the private cache headers. Fix.