Help with captcha on mobile #50758
Replies: 2 comments 2 replies
|
This behavior occurs due to how GoTrue validates configuration reloads, combined with potential service-role bypass in curl testing. 1. Configuration Validation Failure on Missing SecretWhen updating auth configuration via func (c *CaptchaConfiguration) Validate() error {
if !c.Enabled {
return nil
}
if c.Provider != "hcaptcha" && c.Provider != "turnstile" {
return fmt.Errorf("unsupported captcha provider: %s", c.Provider)
}
c.Secret = strings.TrimSpace(c.Secret)
if c.Secret == "" {
return errors.New("captcha provider secret is empty")
}
return nil
}If When configuration validation fails, GoTrue aborts applying the new config and continues running the last valid configuration (where captcha remains disabled). The Management API On your dev project, the secret was likely previously configured in the Dashboard or vault, which allowed To resolve this, supply curl -X PATCH 'https://api.supabase.com/v1/projects/<ref>/config/auth' \
-H "Authorization: Bearer <MANAGEMENT_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"security_captcha_enabled": true,
"security_captcha_provider": "turnstile",
"security_captcha_secret": "<CLOUDFLARE_TURNSTILE_SECRET_KEY>"
}'Alternatively, configure both the provider and secret key directly in the Supabase Dashboard under Project Settings > Authentication > Attack Protection / Bot Detection, which guarantees the secret is persisted before activation. 2. Admin / Service Role Bypass During Curl TestsIn func (a *API) verifyCaptcha(w http.ResponseWriter, req *http.Request) (context.Context, error) {
ctx := req.Context()
config := a.config
if !config.Security.Captcha.Enabled {
return ctx, nil
}
if _, err := a.requireAdminCredentials(w, req); err == nil {
// skip captcha validation if authorization header contains an admin role
return ctx, nil
}
// ...If your curl command included the curl -X POST 'https://<project-ref>.supabase.co/auth/v1/token?grant_type=password' \
-H "apikey: <ANON_KEY>" \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "wrongpassword"
}'With captcha active and using the {
"code": 400,
"error_code": "captcha_failed",
"msg": "captcha protection: request disallowed (no captcha_token found)"
}3. Payload Structure for VerificationWhen passing a Turnstile response token from mobile/web clients, GoTrue expects it inside {
"email": "user@example.com",
"password": "userpassword",
"gotrue_meta_security": {
"captcha_token": "<TURNSTILE_TOKEN>"
}
} |
|
Hi @carczarapp, just checking in to see if providing If that solved the issue and captcha protection is functioning as expected now, please feel free to click Mark as answer so others troubleshooting mobile Turnstile verification can find it easily. |
Uh oh!
There was an error while loading. Please reload this page.
PATCH /v1/projects/ihoatwhdgwngwchvaapc/config/auth with {"security_captcha_enabled": true} returns a 200 confirming the new value, but POST /auth/v1/token?grant_type=password continues to accept requests with no captcha_token — it returns invalid_credentials for bad creds instead of the expected captcha_failed.
Steps to reproduce:
PATCH /v1/projects/ihoatwhdgwngwchvaapc/config/auth with security_captcha_enabled: true, security_captcha_provider: turnstile.
Confirm via GET on the same endpoint that it reads back true.
POST /auth/v1/token?grant_type=password with a bogus email/password and no captcha_token field.
Expected: 400 captcha_failed. Actual: 400 invalid_credentials — captcha is not being enforced.
Confirmed not a client-side issue: tested directly against the GoTrue endpoint via curl, no app code involved.
Confirmed not a config-shape issue: our sibling dev project (ozqlabksvanvzdppdnhi) has an identical config shape (security_captcha_enabled: true, same provider) and enforces correctly and instantly — same test against dev returns captcha_failed as expected.
Timeline: enabled at ~18:10 UTC on 2026-09-22, retested repeatedly for 6+ minutes, including a full disable→re-enable cycle at ~18:20 UTC to force a fresh config apply. Enforcement never took effect in any of these attempts. We've since reverted security_captcha_enabled to false on this project to avoid an unpredictable, unverified change to production auth.
Is there a known propagation issue for this config on prod-tier/us-east-2 projects, or a caching layer between the Management API and the running GoTrue instance? Happy to provide request IDs or re-enable briefly for you to inspect live if useful.
All reactions