auth icon indicating copy to clipboard operation
auth copied to clipboard

Some JWTs exceed Cloudflare header size limits & Nginx defaults

Open yekta opened this issue 1 year ago • 3 comments

Bug report

  • [X] I confirm this is a bug with Supabase, not with my own application.
  • [X] I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

Some JWTs are simply too big in size and they break reasonable header size defaults: Two of which are Cloudflare header size limits and Nginx default header size limits.

The example below is using Google OAuth to sign in to our self-hosted Supabase instance. We use anything but defaults, we are not pushing extra data to the user metadata object etc.

Screenshot 2024-08-31 at 16 25 46

I'm not sure about the reason for including these metadata in JWTs. There have been people having issues with exactly this over the years multiple times (starting with Netlify gotrue). Considering Cloudflare and Nginx are rather large and their limits are not unreasonable, I think gotrue should not break them by default.

A simple solution could be letting people skip the encoding of user metadata in JWTs. Here is a very rough example:

dontEncodeUserMetaData := true
var userMetaData map[string]interface{} = user.UserMetaData
if dontEncodeUserMetaData {
	userMetaData = map[string]interface{}{}
}

claims := &hooks.AccessTokenClaims{
	RegisteredClaims: jwt.RegisteredClaims{
		Subject:   user.ID.String(),
		Audience:  jwt.ClaimStrings{user.Aud},
		IssuedAt:  jwt.NewNumericDate(issuedAt),
		ExpiresAt: jwt.NewNumericDate(expiresAt),
		Issuer:    config.JWT.Issuer,
	},
	Email:                         user.GetEmail(),
	Phone:                         user.GetPhone(),
	AppMetaData:                   appMetaData,
	UserMetaData:                  userMetaData,
	Role:                          user.Role,
	SessionId:                     sid,
	AuthenticatorAssuranceLevel:   aal.String(),
	AuthenticationMethodReference: amr,
	IsAnonymous:                   user.IsAnonymous,
}

Here is the exact same user login with user metadata removed from the JWT. Significantly smaller, however still larger than "usual": Screenshot 2024-08-31 at 16 33 04

I'm willing to create a PR with the fix, however, I'm not sure about the preferred way of handling this. I was thinking it could be a simple env variable which people can use to opt-out of encoding user metadata in the JWT. We're currently running our fork in production and nothing seems to be broken. However, I don't know if there are potential bad implications of simply omitting the user metadata.

Update: I've realized identities are also encoded in this cookie. So if someone is signed in with say 4 different providers and changed their email a couple of times, this guarantees exceeding the majority of all header size limits anywhere not just Cloudflare or Nginx.

To Reproduce

I'm not exactly sure exactly when this happens. It seems to be happening with some Google logins, and not others. Either way, the cookies on average are larger than any auth library I've seen.

Expected behavior

Not hitting header size limits by default.

yekta avatar Aug 31 '24 13:08 yekta

Just to jump on the back of this, this has caused me a decent bit of pain today. I recently updated all my dependencies on a production project, all looked good so it was deployed. However, certain users were having issues logging in, getting 402's and "request header too big" errors.

This bug was the exact issue I was having, and it occurred only after upgrading my Nuxt Supabase version - I'd be more understanding if I was going to an older version of the package.

When a subset of our users logged in using a auth provider (namely the Azure provider), the cookies generated would account for ~7.5kb of size. With the rest of the usual request, this was breaching an 8kb request size, which caused both Cloudflare and the destination NGINX proxy to reject these requests.

It took long enough to figure out the cause, as non-Azure user's had no issues (Azure seems to account for a large chunk of the JWT), and I resolved the NGINX side with some config changes to override the defaults. However, Cloudflare has a hard limit of 8kb for it's request size, which I found no way of resolving, so I ended up having to remove Cloudflare altogether and point users direct to the NGINX server.

For clarity, I am using the nuxt-modules/supabase module as my app is a Nuxt one. A better way to configure what values should be included in a JWT would be ideal. as besides confirming a user is an Azure AD member, and linking a Supabase user to that account, I make no use of the output of Azure's authentication process and could happily strip it from the JWT.

Both Cloudflare and NGINX are production-ready, industry standard tools and consequently, Supabase would benefit by support this out the box, without complex token rewriting hooks or entirely custom JWT implementations.

danperks avatar Oct 08 '24 17:10 danperks

Are there any plans to fix this? We started looking into moving to other auth options specifically because of this issue. I don't see using Supabase going forward unless the issue is fixed. We can't use Supabase Auth and put our site behind Cloudflare which is a deal breaker.

yekta avatar Oct 29 '24 17:10 yekta

Has there been any progress or has someone said anything?

RVP97 avatar Feb 04 '25 22:02 RVP97

@yekta @danperks Did you find a solution to this?

Is it the supabase token?
Or is it the @nuxtjs/supabase package adding the metadata?

When I base64 decode the cookies, the token is only a small part of the cookie data

MichaelJCole avatar May 18 '25 04:05 MichaelJCole

@yekta @danperks Did you find a solution to this?

Is it the supabase token? Or is it the @nuxtjs/supabase package adding the metadata?

When I base64 decode the cookies, the token is only a small part of the cookie data

No. We basically still can't use Cloudflare because of this. It's not just that though, we also can't self-host our app and have to use Vercel because of this since it uses Supabase Auth. There is no update from the team I can see. It caused a whole lot of problems for us as a result of all that. So I'm not using Supabase Auth on a project again until this is fixed.

yekta avatar Aug 28 '25 12:08 yekta

Hi @yekta! Cemal here from Supabase Auth team. Sorry for the inconvenience caused. Have you tried custom access token hooks? You can check the Minimal JWT example at the end of the page and you can exclude the claims. Let me know if it helps.

cemalkilic avatar Aug 28 '25 13:08 cemalkilic

@cemalkilic I did try multiple things more than a year ago. Including forking the entire library and editing what gets sent. I asked for feedback on it as well to fix it myself, didn't get anything actionable out of it. At this point, I'm just not interested in spending a bunch of extra time while complicating the process on a library that is supposed to simplify the process. I'm just using a different Auth library, there are plenty that don't fail by default. I'm saying by default because Cloudflare and Nginx are basically industry defaults. Many users can hit this issue at some point. That is not happening at a large scale because the users of their apps are not signing in with different OAuth methods (2-3 breaks depending on the provider).

This has been an issue that has not been solved ever since Netlify's gotrue. I don't recall how many years is that is. Multiple people reported it. I'm actually amazed that no one seems to care about it for a reason I'm not able to understand.

I like Supabase a lot, I've been using it since it has been 2 months old. I recommended it to many people over the years. I self-hosted it, used the paid hosted version for a good while. The fact that such a glaring issue has taken this longed to be solved, or the fact that I've waited more than a year on an answer is literally the reason I stopped using Supabase on all projects after that particular one. I'm happy with that decision. If in the future Supabase Auth doesn't break by default, I'll come back to see.

yekta avatar Aug 28 '25 13:08 yekta

Any update on this issue?

tuhuynh27 avatar Oct 06 '25 07:10 tuhuynh27