Summary
The get-mapbox-token Edge Function returns the raw Mapbox secret API token to any caller without authentication. Combined with wildcard CORS and verify_jwt = false, any browser tab on any origin can retrieve the live Mapbox token.
Evidence
supabase/functions/get-mapbox-token/index.ts in full:
serve(async (req) => {
if (req.method === "OPTIONS") {
return new Response(null, { headers: corsHeaders });
}
const token = Deno.env.get("MAPBOX_TOKEN");
if (!token) {
return new Response(JSON.stringify({ error: "MAPBOX_TOKEN not configured" }), {
status: 500,
headers: { ...corsHeaders, "Content-Type": "application/json" },
});
}
return new Response(JSON.stringify({ token }), {
headers: { ...corsHeaders, "Content-Type": "application/json" },
});
});
CORS header: "Access-Control-Allow-Origin": "*" — any origin may receive the token.
supabase/config.toml: [functions.get-mapbox-token] verify_jwt = false — no auth required.
Why this matters
A Mapbox secret token grants full API access under the owner's account, including:
- Generating unlimited map tile requests (billable)
- Creating and deleting datasets, tilesets, and styles
- Potentially accessing private datasets if the token has write scopes
The token is returned as plaintext JSON to any HTTP GET or POST request, from any origin, with no credential required. Bots routinely scrape Supabase Edge Function URLs.
Attack or failure scenario
- Attacker sends:
curl https://ldqvretuwballytbywfc.supabase.co/functions/v1/get-mapbox-token
- Response:
{"token":"pk.eyJ..."} — live Mapbox token returned.
- Attacker uses the token to generate tile requests, create datasets, or exhaust the owner's Mapbox quota/billing.
Alternatively, a malicious ad or third-party script on any page embedding this app can fetch() the endpoint and exfiltrate the token cross-origin (wildcard CORS permits it).
Root cause
The function was built to avoid embedding the Mapbox token directly in the frontend bundle (a correct instinct), but the solution — a proxy endpoint that returns the token — provides no actual protection. The endpoint itself must be auth-gated to be useful as a token proxy.
Recommended fix
Option A (correct for a private app): Require a valid Supabase JWT:
- Remove
verify_jwt = false from supabase/config.toml for this function.
- Frontend passes the session token in the
Authorization header when calling the function.
Option B (if truly public tile access is needed): Do not proxy the secret token. Instead:
- Use a Mapbox temporary token scoped to read-only tile access and a specific URL restriction.
- Generate short-lived, scope-restricted tokens server-side and return those, never the master secret.
Option C: Use Mapbox's URL restrictions feature to limit token usage to your production domain only, and use pk.* public tokens (not sk.* secret tokens) directly in the frontend bundle.
Acceptance criteria
Suggested labels
security, bug
Priority
P0
Severity
Critical — live API token for a billable third-party service returned to any unauthenticated caller.
Confidence
Confirmed — code explicitly returns Deno.env.get("MAPBOX_TOKEN") with no auth check and verify_jwt = false.
Summary
The
get-mapbox-tokenEdge Function returns the raw Mapbox secret API token to any caller without authentication. Combined with wildcard CORS andverify_jwt = false, any browser tab on any origin can retrieve the live Mapbox token.Evidence
supabase/functions/get-mapbox-token/index.tsin full:CORS header:
"Access-Control-Allow-Origin": "*"— any origin may receive the token.supabase/config.toml:[functions.get-mapbox-token] verify_jwt = false— no auth required.Why this matters
A Mapbox secret token grants full API access under the owner's account, including:
The token is returned as plaintext JSON to any HTTP GET or POST request, from any origin, with no credential required. Bots routinely scrape Supabase Edge Function URLs.
Attack or failure scenario
curl https://ldqvretuwballytbywfc.supabase.co/functions/v1/get-mapbox-token{"token":"pk.eyJ..."}— live Mapbox token returned.Alternatively, a malicious ad or third-party script on any page embedding this app can
fetch()the endpoint and exfiltrate the token cross-origin (wildcard CORS permits it).Root cause
The function was built to avoid embedding the Mapbox token directly in the frontend bundle (a correct instinct), but the solution — a proxy endpoint that returns the token — provides no actual protection. The endpoint itself must be auth-gated to be useful as a token proxy.
Recommended fix
Option A (correct for a private app): Require a valid Supabase JWT:
verify_jwt = falsefromsupabase/config.tomlfor this function.Authorizationheader when calling the function.Option B (if truly public tile access is needed): Do not proxy the secret token. Instead:
Option C: Use Mapbox's URL restrictions feature to limit token usage to your production domain only, and use
pk.*public tokens (notsk.*secret tokens) directly in the frontend bundle.Acceptance criteria
/functions/v1/get-mapbox-tokenwithout a valid Supabase JWT returns401Suggested labels
security, bug
Priority
P0
Severity
Critical — live API token for a billable third-party service returned to any unauthenticated caller.
Confidence
Confirmed — code explicitly returns
Deno.env.get("MAPBOX_TOKEN")with no auth check andverify_jwt = false.