Skip to content

fix(contact): stop autofill from swallowing submissions - #45

Merged
mjfelis merged 1 commit into
mainfrom
fix/contact-honeypot
Sep 12, 2026
Merged

mjfelis merged 1 commit into
mainfrom
fix/contact-honeypot

Conversation

@mjfelis

@mjfelis mjfelis commented Sep 12, 2026

Copy link
Copy Markdown
Member

Problem

The contact form showed "Message sent" but no email arrived. The ingress log since 21 August holds no POST to /api/contact from a browser, and the pod log has no contact entries: submissions never left the browser.

Cause: the honeypot was a plain text input named website_hp. Browser autofill and password-manager extensions fill off-screen inputs from a saved profile (Chrome ignores autocomplete="off" for address data), and the form's submit handler returned "success" without posting whenever that field had a value.

A second silent drop sat in the API: the time-to-submit check compared the browser's timestamp with the server clock, so any visitor whose clock ran ahead by a couple of seconds was dropped with a success response and no log line.

Fix

  • Honeypot renamed hp_check, tagged with the LastPass, 1Password and Bitwarden ignore attributes, and only inspected by the API. The client short-circuit is gone.
  • The browser now sends the elapsed time it measured (elapsed_ms); the API no longer compares two clocks.
  • Both drops answer success to the browser as before but log [contact] dropped: ... with the reason. README notes what to grep for.

Verified

Type-check, unit tests, build. Standalone server exercised: honeypot filled and a 800 ms submission both answer ok and log their reason; a normal submission reaches the delivery path. The rendered form carries hp_check and no website_hp or rendered_at. The SMTP path itself was confirmed working in production with a direct API call before this change.

The honeypot was a text input named website_hp that browser autofill and
password managers filled from a saved profile; the form then showed
"Message sent" without posting anything. No submission had reached the API
since deployment. The field is renamed hp_check, tagged so extensions skip
it, and only the API inspects it. The time-to-submit check now uses the
elapsed time the browser measured instead of comparing the browser's
timestamp with the server clock, which dropped visitors whose clock ran
ahead. Both drops are logged with their reason.
@mjfelis
mjfelis merged commit d4ed474 into main Sep 12, 2026
1 check passed
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.

1 participant