Skip to content

fix: validate JWT signature in upload-avatar endpoint#91

Open
FuturMix wants to merge 1 commit into
profullstack:masterfrom
FuturMix:fix/avatar-jwt-validation
Open

fix: validate JWT signature in upload-avatar endpoint#91
FuturMix wants to merge 1 commit into
profullstack:masterfrom
FuturMix:fix/avatar-jwt-validation

Conversation

@FuturMix

Copy link
Copy Markdown

Summary

Fixes #90 — the upload-avatar endpoint decoded JWT payloads with atob() without verifying the cryptographic signature, allowing token forgery.

Changes

  • Replaced manual JWT decoding (token.split('.') → atob → JSON.parse) with supabase.auth.getUser(token) which validates the signature via Supabase Auth
  • Extracted a shared getAuthenticatedUser() helper used by both POST and DELETE handlers
  • Kept the service role client for storage/DB operations (required for avatar bucket writes)

Before (vulnerable)

const payload = JSON.parse(atob(token.split('.')[1]));
user = { id: payload.sub };  // trusts unsigned payload

An attacker could craft eyJ...<forged-payload>...<any-signature> with any sub and upload avatars for other users.

After (secure)

const { data: { user }, error } = await authClient.auth.getUser(token);

Supabase validates the JWT signature against its signing secret. Forged tokens are rejected.

Verification

// This now correctly returns 401:
const fakePayload = btoa(JSON.stringify({
  sub: 'victim-user-id',
  exp: Math.floor(Date.now() / 1000) + 3600
}));
const fakeToken = `eyJhbGciOiJIUzI1NiJ9.${fakePayload}.fakesig`;

fetch('/api/auth/upload-avatar', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${fakeToken}` },
  body: formData
});
// → 401 { error: 'Invalid authentication token' }

Risk assessment

  • Behavioral change: None for legitimate callers — they pass valid Supabase JWTs which getUser() accepts
  • Net code change: -86 lines of manual JWT parsing, +45 lines using Supabase's auth API
  • Dependencies: No new dependencies — @supabase/supabase-js already imported

Replace manual JWT payload decoding (atob) with
supabase.auth.getUser(token) which cryptographically verifies
the token signature. The previous code trusted the JWT payload
without checking the signature, allowing an attacker to craft a
token with an arbitrary sub claim and upload/delete avatars for
other users.

Fixes profullstack#90
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: upload-avatar endpoint trusts JWT payload without verifying signature

1 participant