@BETTER-AUTH/EXPO · GHSA-4wq4-2ppv-q3hg · Package
FIX → 1.8.0-beta.5 +1
The expo() plugin in @better-auth/expo signed a caller-supplied state value with the application secret and returned it in a cookie. An unauthenticated attacker who knows a user's email can sign in as that user and change the account's email address.
first public Nov 3, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Applications whose server registers the expo() plugin from @better-auth/expo 1.4.0-beta.6 or later are exposed, with no other setting required. The wildcard open-redirect and trusted-origin issues additionally need a wildcard entry in trustedOrigins. Servers that do not use Expo social sign-in can remove the expo() plugin instead.
Not affected if no-expo-plugin, versions-patched
Who cares auth, better-auth, expo, node
expo() plugin from @better-auth/expo at version 1.4.0-beta.6 or later.You are affected if your server registers the expo() plugin from @better-auth/expo 1.4.0-beta.6 or later. No other setting is needed.
The wildcard origin problem below also needs a wildcard entry in trustedOrigins, such as myapp://* or https://*.example.com.
Signing values it did not issue. The expo() plugin adds a public endpoint that helps the system browser start a social sign-in. The endpoint signed a value taken from the request with the application secret and returned the signature in a cookie. Better Auth uses the same secret for email verification links and, when enabled, the session cookie cache.
Open redirect. The same endpoint could redirect a visitor to any external HTTPS site.
Wildcard trusted origins. A wildcard entry in trustedOrigins could match URLs outside the intended scheme, host, or path.
An unauthenticated attacker who knows a user's email address can sign in as that user and change the account's email address, with no action from the user. With the session cookie cache enabled, an attacker who knows a user's ID can also act as that user.
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
@better-auth/expo and better-auth with npm ls @better-auth/expo better-auth.trustedOrigins contains a wildcard entry such as myapp://* or https://*.example.com.Upgrade to 1.8.0-beta.5 +1
@better-auth/expo to 1.7.16 on the 1.7 line, or 1.8.0-beta.5 on the beta line.better-auth to 1.7.16 on the 1.7 line, or 1.8.0-beta.5 on the beta line.The open redirect can make phishing links that start on your auth origin look more convincing. The wildcard problem can let a URL you did not mean to trust pass the trusted origin check.
Upgrade both @better-auth/expo and better-auth to 1.7.16, or to 1.8.0-beta.5 on the beta line.
After upgrading, rotate the application secret if the endpoint was reachable. Signatures issued before the fix stay valid until the secret changes.
If Expo sign-in through an SSO identity provider fails after upgrading, add the identity provider's origin to trustedOrigins.
If you do not use Expo social sign-in, remove the expo() server plugin.
Otherwise, block requests to /expo-authorization-proxy (under your auth base path) whose authorizationURL carries a state value that is not exactly 32 characters from A-Z, a-z, 0-9, - and _. State values that Better Auth issues always have this form. This blocks the signing problem only.
The endpoint read state from the caller-supplied authorization URL and stored it in a signed cookie without checking that the server had issued it. The cookie signature is an HMAC-SHA256 keyed with the application secret. That is the same computation as an HS256 JSON Web Token signature and as the compact session cookie cache signature, so a forged email-change token or cookie cache value was accepted.
The fix signs only an unexpired state the server issued, and redirects only to the authorization endpoint origin of a configured social, generic OAuth, or trusted SSO provider. Wildcard trusted origins now match a URL by its parsed scheme, host, and path, and no longer match a URL with userinfo or one that cannot be parsed. A wildcard host made only of digits, dots, and wildcards, such as 192.168.*.*, now matches only IPv4 addresses.