Comments: Turnstile widget is rendered but its token is never verified server-side #1780
khoinguyenpham04
announced in
Roadmap
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
This Roadmap discussion mirrors #1589: Comments: Turnstile widget is rendered but its token is never verified server-side.
Use this discussion to upvote the roadmap item and discuss priority, use cases, and product feedback. Keep implementation tracking, reproduction details, and PR-specific feedback on the source issue.
bot:failed,bot:enhancementOriginal Issue
Summary
The built-in comments UI renders a Cloudflare Turnstile widget and submits its token, but the public comment POST route never verifies that token server-side. Enabling Turnstile on comments therefore provides only client-side friction — a bot that POSTs directly to the API (skipping the widget) is not blocked.
Details
packages/core/src/components/CommentForm.astro:<div class="cf-turnstile" data-sitekey={turnstileSiteKey}>whenturnstileSiteKeyis passed.https://challenges.cloudflare.com/turnstile/v0/api.js.[name='cf-turnstile-response']and includes it asturnstileTokenin the JSON POST body.But
packages/core/src/astro/routes/api/comments/[collection]/[contentId]/index.ts(the public POST handler) only runs:website_url)It parses the body but ignores
turnstileToken— there is nositeverifycall anywhere inpackages/core(grep forturnstile/siteverifyreturns onlyCommentForm.astro).Why this matters
A site owner who sets
turnstileSiteKeyreasonably assumes submissions are gated by Turnstile. They aren't. This is particularly dangerous combined withcommentsModeration: "none"(auto-approve): direct-to-API spam is auto-published with no human review and no Turnstile enforcement.The pattern already exists in-repo
@emdash-cms/plugin-formsalready verifies Turnstile correctly —src/turnstile.tsexposesverifyTurnstile(token, secretKey, httpFetch)hittinghttps://challenges.cloudflare.com/turnstile/v0/siteverify, used inhandlers/submit.ts. Comments should do the same.Suggested fix
In the comment POST route, when a Turnstile secret is configured (e.g. a
TURNSTILE_SECRETsecret / config field, mirroringipSaltresolution), call siteverify with the submittedturnstileTokenand reject on failure before persisting/moderating. Reuse theplugin-formsverifyTurnstilelogic. Skip when no secret is configured so existing non-Turnstile sites are unaffected (backward compatible).Happy to send a PR wiring this up if it's wanted.
Environment
Beta Was this translation helpful? Give feedback.
All reactions