Identity-provider avatars are cropped through imageutils.Decode. When the
server is busy the avatar is skipped and logged, like any other avatar
sync error, so the login still succeeds.
Project background uploads (and migrated backgrounds) are decoded through
imageutils.Decode, which also covers the blur hash computed from the
decoded image. A busy server answers 503. Drops the unused CreateBlurHash,
which decoded without any bound.
Uploaded avatars are decoded through imageutils.Decode on upload and when
resizing per size, so a busy server answers 503 instead of decoding in
parallel. The old avatar file is removed only after the new one decoded,
since a storage delete is not rolled back with the session.
Attachment previews now decode through imageutils.Decode, which holds an
image's pixels against one process-wide budget until the caller is done
with the decoded image. Other decode sites move onto it next.
Address pr-swarm finding: after the GHSA-j5v7 key rename the server
exposes views_buckets_{create,update} and views_buckets_tasks_update, so
new bot tokens could no longer move tasks between buckets. Old names stay
for older servers.
Address pr-swarm finding: the item cap ran only after data.json was fully
decoded into tasks, so a file of millions of bare objects still exhausted
memory.
Colliding non-CRUD routes got a method suffix in registration order, per
version, so one key granted different actions on v1 and v2: a read-only
projects.background scope deleted backgrounds through v2, and bucket
create/update keys swapped meaning (GHSA-j5v7-qcwp-5g32). Keys now derive
from the full v1+v2 route set and carry the action (read/create/update/
delete) once a subkey has more than one. Marking all notifications as
read gets its own key on both versions instead of overwriting update.
The archive holds the config, the full database and every blob, but was
created with the umask mode and followed or clobbered an existing path.
Refs GHSA-rp64-xg8g-9mpr
A re-export only moved the pointer, leaving the previous archive on disk
forever. A failed export rolled back the row but kept the blob, and the OS
temp zip was only removed on success.
Refs GHSA-7gmh-4fw6-8xc5
A cross-site <form> needs no CORS preflight, and v2 decoded form bodies
API-wide, so a form POST to /login or the OIDC callback minted a session
in the victim's browser (GHSA-frf4-3prf-3vch). Form decoding is now
scoped to /oauth/token, and both API groups answer 415 elsewhere.