Skip to content

Test that Turnstile rejects a verified token for an unlisted hostname#51

Merged
mberman84 merged 2 commits into
Forward-Future:mainfrom
HMAKT99:test/turnstile-hostname-mismatch
Jun 21, 2026
Merged

Test that Turnstile rejects a verified token for an unlisted hostname#51
mberman84 merged 2 commits into
Forward-Future:mainfrom
HMAKT99:test/turnstile-hostname-mismatch

Conversation

@HMAKT99

@HMAKT99 HMAKT99 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Summary

verifyTurnstile() rejects a Siteverify success whose hostname isn't in the TURNSTILE_HOSTNAMES allow-list:

if (!parseList(env.TURNSTILE_HOSTNAMES).includes(result.hostname)) {
  return { valid: false, reason: "hostname_mismatch" };
}

This is a meaningful defense — it stops a Turnstile token solved on an attacker-controlled page (a different hostname) from being replayed against this form. But the branch had no test coverage: the Siteverify test double always returned the allow-listed signals.forwardfuture.ai, so a regression that dropped or weakened the hostname check would pass CI.

Change

Adds a wrong-hostname-token to the Siteverify mock that returns success: true with the correct action but an unlisted hostname, plus a test asserting the submission is rejected (400 / verification_failed) with no Site Data write, while confirming Siteverify was actually consulted.

Test-only; no behavior change. Worker suite goes from 14 → 15 passing.

Verification

  • npm --prefix worker run check → 15/15 tests pass.

The gateway rejects a Siteverify success whose hostname is not in
TURNSTILE_HOSTNAMES, which stops a token minted for an attacker-controlled
page from being replayed against this form. That branch had no coverage:
the test double always returned the allow-listed hostname. Add a token that
resolves to an unlisted hostname and assert the submission is rejected with
verification_failed and no Site Data write, after Siteverify was consulted.
@HMAKT99

HMAKT99 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

Test-only. The gateway rejects a Turnstile success whose hostname isn't allow-listed (which stops a token solved on an attacker's page from being replayed here), but that branch had no coverage — the Siteverify double always returned the allow-listed hostname, so a regression would pass CI silently.

This adds a token that resolves to an unlisted hostname and asserts the submission is rejected with no Site Data write. Worker suite goes 14 → 15 green. Hopefully a low-risk safety net.

@mberman84 mberman84 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. The test specifically exercises a successful Siteverify response with the expected action but an unlisted hostname, then verifies the 400 verification failure, one Siteverify call, and no Site Data write. It remains isolated and passes on the synthesized merge with current main.

@mberman84 mberman84 merged commit 77b9115 into Forward-Future:main Jun 21, 2026
1 check passed
@HMAKT99

HMAKT99 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review and approval!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants