You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The 8h localStorage HMAC is accepted without re-checking the GitHub session #70
/api/submit authenticates callers with an HMAC over the GitHub login: handleFormSubmit (cloudflare-worker/index.js:785-789) requires github_auth.login + github_auth.sig and verifies with hmacVerify(login, sig, GITHUB_OAUTH_HMAC_KEY). The signature is minted once at OAuth callback (index.js:588) and cached client-side in localStorage by app/composables/useAuth.ts with AUTH_TTL = 8 * 60 * 60 * 1000.
Nothing re-checks that the underlying GitHub session is still valid. For up to 8 hours after the user's actual GitHub session ends — or after the mctl_auth blob is copied off the machine — that value keeps working against /api/submit. The signature has no expiry of its own either: it covers only the login string, so the 8h bound is enforced entirely by the client that holds it. A copied blob can simply have its exp rewritten.
Raised while scoping #66 and deliberately left out of it, because the fix is a different shape than "add Turnstile". Note #66's operator decision extends this same credential to GET /api/github/check-team, so it now gates two endpoints rather than one — which strengthens the case for fixing it in one place instead of inventing a second, stronger gate for the lesser endpoint.
Expected direction
Any one of these closes it; the first is smallest:
Put an expiry inside the signed payload — sign login|exp rather than login, and reject server-side once exp passes. The client can no longer extend its own credential by editing localStorage, and the 8h bound becomes real.
Or bind the signature to the server-side OAuth session and re-check that session on submit.
Or drop the client-held credential entirely and authenticate submit from the __gh_session cookie.
Acceptance criteria
A mctl_auth value with a locally edited exp is rejected once the server-side expiry passes.
The signed material is no longer a bare, indefinitely-valid login string.
/api/submit and /api/github/check-team keep working for a normally signed-in user.
Activity