Hall of Fame image from https://openclipart.org/detail/120343/trophy
Back to Hall of Fame Contents Back to Wekan Website

Contents / AuthorBleed

CVE Vulnerability name Date Responsible Security Disclosure by Vulnerabilities
GHSA-6jr3-42jf-vhm5

AuthorBleed

2026-08-15 ybsun0215 and xet7

Coordinated disclosure via GitHub Security Advisory GHSA-6jr3-42jf-vhm5.
  • AuthorBleed — six server paths took the actor's identity from the request body's authorId field, checking only that such a user exists, so a board member could record card creations, card deletions and custom fields as somebody else (CWE-345 Insufficient Verification of Data Authenticity)
  • The board's own history is the thing at stake. "victim created this card" and "victim deleted this card" became attacker-controlled sentences, on any board the caller may write to, and the card document itself recorded the forged userId as its creator
  • The six: single card create, bulk card create, linked-card create, single card delete, bulk card delete, and custom-field create
  • WeKan had already accepted this exact class as a vulnerability and fixed it for card comments in 8.19, and again for the card PUT handler — whose inline note still reads "use req.userId consistently (it previously read req.body.authorId here)". These six paths were missed, which makes it an incomplete fix rather than a new decision
  • All six read req.userId now — the session the request authenticated as, which is the only identity the server can vouch for. The parameter does appear in historical API documentation, but that documentation predates the 8.19 fix of the same pattern
  • Fixed at upcoming WeKan release


Details

AuthorBleed — attribution taken from the request body (CWE-345)

Six paths recorded who did something from a field the caller sends:

POST   /api/boards/{boardId}/lists/{listId}/cards            (single, and the linked form)
POST   /api/boards/{boardId}/lists/{listId}/cards/bulk
DELETE /api/boards/{boardId}/lists/{listId}/cards/{cardId}
DELETE /api/boards/{boardId}/cards/bulk
POST   /api/boards/{boardId}/custom-fields
    

The check was that the named user exists — not that it is the caller:

// server/models/cards.js — before
const checkUser = await ReactiveCache.getUser(req.body.authorId); // existence only
...
userId: req.body.authorId,                    // recorded as the card's creator
await cardCreation(req.body.authorId, card);  // and in the activity feed
    

An existence check is not an authentication check. It confirms that the name in the envelope belongs to somebody; it says nothing about who wrote the letter.

For comparison, the comment endpoint fixed in 8.19 uses the session:

// server/models/cardComments.js
userId: req.userId,
    

Every one of the six does the same now. tests/restApiIdorBatch.test.cjs pins each path by what it records, and that no card or custom-field path reads authorId from the body again.



Back to Hall of Fame Contents Back to Wekan Website