Bulwark Webmail: Two Routes Mint Identity Cookies Without a Check
Two endpoints issue the encrypted identity cookies for a freely chosen username without checking that claim against the mail server
Advisory ID: TP-2026-100
Product: Bulwark Webmail (web interface for the Stalwart mail server, Next.js)
Vulnerability type: Improper authentication (CWE-287)
CVE: requested on 19 September 2026 (GitHub CNA), assignment pending
CVSS 3.1: 8.2 (High) · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Affected versions: <= 1.9.2
Vendor advisory: GHSA-wxcm-j4jc-9fxq
Fixed in: 1.10.0
Reported: 16 September 2026
Summary
Bulwark Webmail keeps a signed-in user's identity in two server-encrypted cookies. Two endpoints issue those cookies for a username the caller names, and do not check that claim against the mail server. When the supplied server address matches the configured JMAP server, which is the normal case, both routes take the trusted-upstream branch and skip credential verification entirely. The resulting cookie is cryptographically valid, so the downstream check accepts it. An attacker with no account on the instance and none on the mail server thereby reads, overwrites and deletes any user's synced settings.
Root cause
The endpoints POST /api/auth/stalwart-context and POST /api/auth/session issue the identity cookies for the supplied username and never call verifyJmapAuth() once the supplied server address matches the configured JMAP server. The checking routine verifyIdentity() compares only the username claim in the decrypted cookie against the requested account and never re-checks the credential it carries. Together these close a loop: one side issues a valid cookie without proof, the other accepts any valid cookie as proof. This is a bypass of the fix for CVE-2026-34834, which removed the fallback for callers with no cookie at all; that fallback is indeed gone, since a cookie-less call is rejected. The minting routes simply hand the attacker the missing cookie.
Proof of Concept
# with no account on the instance and none on the mail server:
POST /api/auth/session
{"username": "[email protected]", "serverUrl": "<the configured JMAP server>"}
# the response sets jmap_session and jmap_stalwart_ctx for the foreign account.
# with those cookies, read, overwrite or delete the victim's synced settings.
Reading and writing other users' settings requires Settings Sync to be active. The environment path defaults it off, but the shipped setup wizard turns it on, and the published workaround for CVE-2026-34834 was precisely to disable it. The cookie minting itself needs no non-default option.
Impact
- Reading, overwriting and deleting the synced settings of any user by an attacker with no account at all.
- Passing every other sign-in gate in the product that builds on the same verification routine.
- No account on the instance and none on the mail server needed; the attack starts entirely anonymously.
- Bypass of an already published fix, which left operators believing the hole was closed.
References
Is Something Like This in Your Software?
Our team found this vulnerability in the course of its work. Have your applications tested by the same specialists, with a penetration test from turingpoint.
