-
-
Notifications
You must be signed in to change notification settings - Fork 95
Open
Description
- I confirm this is a bug with Supabase, not with my own application.
- I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
CORS preflight requests fail when Access-Control-Allow-Headers uses different casing than what browsers send in Access-Control-Request-Headers. Per RFC 7230, HTTP header names are case-insensitive, but Edge Functions appears to perform case-sensitive comparison.
Browsers convert all headers to lowercase in Access-Control-Request-Headers (per CORS spec), so the server-side comparison must be case-insensitive to comply with RFC 7230.
To Reproduce
- Deploy an Edge Function with CORS headers using mixed case:
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'X-Idempotency-Key'
}
Deno.serve(async (req) => {
if (req.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders })
}
return new Response('OK', { headers: corsHeaders })
})- Call the function from a browser with the same header:
fetch('https://xxx.supabase.co/functions/v1/test', {
method: 'POST',
headers: { 'X-Idempotency-Key': 'abc123' }
})- Observe CORS error: "Request header field x-idempotency-key is not allowed"
Expected behavior
Preflight should succeed because x-idempotency-key and X-Idempotency-Key are the same header per RFC 7230 Section 3.2: "Each header field consists of a case-insensitive field name..."
System information
- OS: macOS
- Browser: Chrome, Firefox, Safari (all exhibit same behavior)
- Version of supabase-js: 2.x
- Version of Node.js: 20.x
Additional context
Workaround: Include both cases in allowed headers:
'Access-Control-Allow-Headers': 'x-idempotency-key, X-Idempotency-Key'References:
- Original research: bdougie/contributor.info#729
- Similar bug/fix in Quarkus: quarkusio/quarkus#3681
Metadata
Metadata
Assignees
Labels
No labels