CRZ-008
Auth cookie without SameSite; GET endpoints accept mw alone
medium
CVSS 3.1: 4.2 · Asset: admin.corezoid.com
- Severity: Medium
- CVSS 3.1:
AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N→ 4.2 - CWE: CWE-1275 (Sensitive Cookie with Improper SameSite Attribute)
- Asset:
https://admin.corezoid.com(and via cookie domain, any*.corezoid.com) - Discovered: 2026-04-26
- Status: Open
Summary
The admin.corezoid.com application sets two paired
authentication cookies with the same value (mw and
__Host_mw):
Set-Cookie: mw=<b64...>; Domain=.corezoid.com; Path=/; HttpOnly; Secure (NO SameSite)
Set-Cookie: __Host_mw=<b64...>; Domain=.corezoid.com; Path=/; HttpOnly; Secure; SameSite=Strict
mwhas no SameSite attribute → browsers default toSameSite=Lax, meaning it is sent on top-level cross-site GET navigations__Host_mwhasSameSite=Strict(which is good) BUT the name is not truly__Host-prefixed (uses underscore_, not hyphen-), so browsers treat it as a regular cookie, not a__Host-prefixed cookie. That said, Strict alone does prevent cross-site sending.
Impact — partial CSRF / information leak via Lax cookie
Testing confirms:
| Endpoint | Auth result with mw alone |
Auth result with both cookies |
|---|---|---|
GET /auth/me |
200 (full profile + superuser status + siteheart_auth token) | 200 |
GET /auth/me/state_changes |
200 (financial data:
total_balance: -12000000) |
200 |
GET /system/conf |
200 (widget URLs, auth providers) | 200 |
GET /logout |
200 (state-changing!) | 200 |
POST /auth/me |
{"redirect":"/enter"} |
200 |
POST /api/2/json |
{"proc":"error","description":"cookie or headers are not valid"} |
200 |
What's exploitable in a real browser cross-site attack:
The mw cookie (SameSite=Lax by default) IS
sent on top-level cross-site GET navigations. Scenarios:
- Forced logout (CSRF). Attacker hosts
<img src="https://admin.corezoid.com/logout">or tricks the user into visiting<a href="https://admin.corezoid.com/logout">click me</a>. With Lax default, themwcookie is sent → logout endpoint acceptsmwalone → user is logged out. Annoyance vector, not data theft. - Information disclosure via subdomain-takeover. The
mwcookie hasDomain=.corezoid.com. If any subdomain under*.corezoid.comis compromised (subdomain takeover, XSS, abandoned S3 bucket, dev host with weak auth), the attacker JavaScript on that subdomain can:- Read
mwcookie (actually no, it's HttpOnly — can't be read by JS directly) - BUT:
fetch('/auth/me', {credentials:'include'})from the compromised subdomain toadmin.corezoid.com— blocked by CORS (no Access-Control-Allow-Origin) - Direct GETs from the compromised subdomain to admin.corezoid.com would fire, but the response body stays opaque
- The real risk: a new XSS on admin.corezoid.com has immediate access to the full authenticated API surface via same-origin requests
- Read
- Leaked dev endpoint with cookie echo. Any endpoint
that reflects arbitrary content from
*.corezoid.com+ the Lax cookie combines to create a reliable exfiltration channel.
Test payload (NOT deployed — CSRF PoC concept)
<!-- attacker site -->
<iframe src="https://admin.corezoid.com/logout" width=0 height=0></iframe>
<!-- or -->
<a href="https://admin.corezoid.com/logout">Click here for your coupon</a>
Because /logout accepts GET with mw alone,
and mw is Lax (sent on top-level nav), the victim is logged
out. Low impact but demonstrably exploitable CSRF.
Remediation
Priority 1 — quick wins:
- Set
SameSite=Strict(or at leastLax) on themwcookie explicitly. Lax default is not identical to explicit Lax (spec says "Lax" but implementations vary; some browsers treated missing SameSite as None until 2020). - Rename
__Host_mwto__Host-mw(underscore → hyphen) so browsers actually enforce host-prefix rules. Currently the double underscore is a misleading label, not a real security feature. - Collapse the dual-cookie scheme. Having two cookies
with identical content and different SameSite defeats the purpose — if
mwis accepted alone on GET endpoints, the Strict flag on__Host_mwis security theater.
Priority 2 — server-side defenses:
- Require both cookies on GET endpoints too. Right
now
GET /auth/meacceptsmwalone. This is the actual bug enabling the information disclosure. - Change
/logouttoPOSTonly, and require CSRF token in POST body. - Reduce cookie
Domain=.corezoid.comscope to justadmin.corezoid.com. The session cookie does not need to be sent tobook.corezoid.com,market.corezoid.com, etc.
References
- CWE-1275: Sensitive Cookie with Improper SameSite Attribute
- OWASP SameSite Cookie guide
- MDN: Using HTTP cookies — SameSite