-
-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: do not send non-JWTs in Authorization
header
#1293
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,3 +66,60 @@ export function applySettingDefaults< | |
|
||
return result | ||
} | ||
|
||
export const BASE64URL_REGEX = /^([a-z0-9_-]{4})*($|[a-z0-9_-]{3}$|[a-z0-9_-]{2}$)$/i | ||
|
||
/** | ||
* Checks that the value somewhat looks like a JWT, does not do any additional parsing or verification. | ||
*/ | ||
export function isJWT(value: string): boolean { | ||
if (value.startsWith('Bearer ')) { | ||
value = value.substring('Bearer '.length) | ||
} | ||
|
||
value = value.trim() | ||
|
||
if (!value) { | ||
return false | ||
} | ||
|
||
const parts = value.split('.') | ||
|
||
if (parts.length !== 3) { | ||
return false | ||
} | ||
|
||
for (let i = 0; i < parts.length; i += 1) { | ||
const part = parts[i] | ||
|
||
if (part.length < 4 || !BASE64URL_REGEX.test(part)) { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} | ||
|
||
export function checkAuthorizationHeader(headers: { [header: string]: string }) { | ||
if (headers.authorization && headers.Authorization) { | ||
console.warn( | ||
'@supabase-js: Both `authorization` and `Authorization` headers specified in createClient options. `Authorization` will be used.' | ||
) | ||
|
||
delete headers.authorization | ||
} | ||
|
||
const authorization = headers.Authorization ?? headers.authorization ?? null | ||
|
||
if (!authorization) { | ||
return | ||
} | ||
|
||
if (authorization.startsWith('Bearer ') && authorization.length > 'Bearer '.length) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
not immediately obvious what this check is for? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like it's making sure that we only check for a valid JWT if the authorization header actually has a value after "Bearer ". It's worth noting that this check will not cover a scenario where someone only passes in "Bearer" (without a trailing space), but I'm guessing this whole scenario would be extremely rare anyway. Still, you might consider covering both. |
||
if (!isJWT(authorization)) { | ||
throw new Error( | ||
'@supabase-js: createClient called with global Authorization header that does not contain a JWT' | ||
) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we initialise the
headers
field using theHeaders
interface instead since it's case-insensitive? (https://developer.mozilla.org/en-US/docs/Web/API/Headers)