fix(forms): harden honeypot hiding on contact + inline lead forms
Deploy to Production / Build & Verify (push) Has been cancelled
Deploy to Production / Pre-Deploy Tests (push) Has been cancelled
Deploy to Production / Deploy to Railway (push) Has been cancelled
Deploy to Production / Deploy to Render (push) Has been cancelled
Deploy to Production / Deploy to VPS (PM2) (push) Has been cancelled
Deploy to Production / Deploy to Fly.io (push) Has been cancelled
Deploy to Production / Post-Deploy Verification (push) Has been cancelled
Deploy to Production / Notify on Failure (push) Has been cancelled
E2E Test Suite / Smoke Tests (P0) (push) Has been cancelled
E2E Test Suite / Critical User Journeys (push) Has been cancelled
E2E Test Suite / API Integration Tests (push) Has been cancelled
E2E Test Suite / Form Interaction Tests (push) Has been cancelled
E2E Test Suite / Destructive & Chaos Tests (push) Has been cancelled
E2E Test Suite / Cross-Browser Regression (chromium) (push) Has been cancelled
E2E Test Suite / Cross-Browser Regression (firefox) (push) Has been cancelled
E2E Test Suite / Cross-Browser Regression (webkit) (push) Has been cancelled
E2E Test Suite / Mobile Device Tests (push) Has been cancelled
E2E Test Suite / Security Header Tests (push) Has been cancelled
E2E Test Suite / Test Report Summary (push) Has been cancelled
Ping Search Engines / Notify Search Engines (push) Failing after 12m31s
Deploy to Production / Build & Verify (push) Has been cancelled
Deploy to Production / Pre-Deploy Tests (push) Has been cancelled
Deploy to Production / Deploy to Railway (push) Has been cancelled
Deploy to Production / Deploy to Render (push) Has been cancelled
Deploy to Production / Deploy to VPS (PM2) (push) Has been cancelled
Deploy to Production / Deploy to Fly.io (push) Has been cancelled
Deploy to Production / Post-Deploy Verification (push) Has been cancelled
Deploy to Production / Notify on Failure (push) Has been cancelled
E2E Test Suite / Smoke Tests (P0) (push) Has been cancelled
E2E Test Suite / Critical User Journeys (push) Has been cancelled
E2E Test Suite / API Integration Tests (push) Has been cancelled
E2E Test Suite / Form Interaction Tests (push) Has been cancelled
E2E Test Suite / Destructive & Chaos Tests (push) Has been cancelled
E2E Test Suite / Cross-Browser Regression (chromium) (push) Has been cancelled
E2E Test Suite / Cross-Browser Regression (firefox) (push) Has been cancelled
E2E Test Suite / Cross-Browser Regression (webkit) (push) Has been cancelled
E2E Test Suite / Mobile Device Tests (push) Has been cancelled
E2E Test Suite / Security Header Tests (push) Has been cancelled
E2E Test Suite / Test Report Summary (push) Has been cancelled
Ping Search Engines / Notify Search Engines (push) Failing after 12m31s
Both honeypots now use off-screen positioning (position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden) instead of relying on a parent's aria-hidden alone, and the input itself carries tabindex="-1", autocomplete="off", and aria-hidden="true". Labels are sr-only and sit as siblings of the input (no nested label/input). Avoid display:none and visibility:hidden so bots that skip those still trip the trap. Verified: rendered honeypot HTML matches spec on both /contact and the homepage inline lead form, and /api/contact still 200s a populated `website` silently (bot path) while accepting empty `website` payloads as real leads.
This commit is contained in:
@@ -54,15 +54,26 @@
|
|||||||
data-testid="inline-lead-form"
|
data-testid="inline-lead-form"
|
||||||
novalidate
|
novalidate
|
||||||
>
|
>
|
||||||
<!-- Honeypot (visually & SR-hidden — bots fill it, real users do not). -->
|
<!--
|
||||||
<div class="absolute -left-[9999px] top-auto w-px h-px overflow-hidden" aria-hidden="true">
|
Honeypot — off-screen positioned, NOT display:none / visibility:hidden
|
||||||
<label for="inline-lead-website">Website</label>
|
(some bots skip those entirely). aria-hidden + sr-only label keep it
|
||||||
|
silent for screen readers; tabindex="-1" + autocomplete="off" keep it
|
||||||
|
out of the tab order and browser autofill. Bots that blindly fill
|
||||||
|
every field will populate `website`, and /api/contact silently drops
|
||||||
|
the submission.
|
||||||
|
-->
|
||||||
|
<div
|
||||||
|
class="absolute -left-[9999px] top-auto w-px h-px overflow-hidden"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<label for="inline-lead-website" class="sr-only">Website</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="inline-lead-website"
|
id="inline-lead-website"
|
||||||
name="website"
|
name="website"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+22
-12
@@ -156,18 +156,28 @@ const trustStats = [
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="contact-form" class="space-y-5" novalidate>
|
<form id="contact-form" class="space-y-5" novalidate>
|
||||||
<!-- Honeypot field (anti-spam) - hidden from users -->
|
<!--
|
||||||
<div class="absolute -left-[9999px]" aria-hidden="true">
|
Honeypot field (anti-spam).
|
||||||
<label for="website">
|
Hidden from sighted users via off-screen positioning (NOT display:none /
|
||||||
Website
|
visibility:hidden — some bots skip those entirely and never trip the trap).
|
||||||
<input
|
The wrapper carries aria-hidden so screen-readers don't announce the label
|
||||||
type="text"
|
or the input, and tabindex="-1" + autocomplete="off" keep it out of the
|
||||||
id="website"
|
tab order and browser autofill. Bots that blindly fill every field will
|
||||||
name="website"
|
set a value here, and /api/contact silently discards the submission.
|
||||||
tabindex="-1"
|
-->
|
||||||
autocomplete="off"
|
<div
|
||||||
/>
|
class="absolute -left-[9999px] top-auto w-px h-px overflow-hidden"
|
||||||
</label>
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<label for="website" class="sr-only">Website</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="website"
|
||||||
|
name="website"
|
||||||
|
tabindex="-1"
|
||||||
|
autocomplete="off"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Name + Email row -->
|
<!-- Name + Email row -->
|
||||||
|
|||||||
Reference in New Issue
Block a user