Fix contact honeypot so browser autofill does not swallow submissions.

Rename the trap field away from "website" and keep legacy detection so real messages still reach Telegram.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Artemii Peretiachenko 2026-07-26 19:16:36 +02:00
parent 793d093c86
commit 1d5596db5f
11 changed files with 34 additions and 22 deletions

View file

@ -104,6 +104,6 @@ Backup is written even if Telegram fails (`telegram_ok: false`), so you still ha
## Behaviour notes
- Honeypot field `website`: if filled, returns `200` without notifying Telegram or writing a backup.
- Honeypot field `hp_company` (legacy `website` still checked): if filled, returns `200` without notifying Telegram or writing a backup.
- In-memory rate limit: 5 POSTs per IP per 60 seconds → `429`.
- Field limits: name/contact ≤ 200 chars, message ≤ 4000.

View file

@ -114,9 +114,11 @@ def validate_fields(data: dict) -> tuple[str, str, str] | str:
return "invalid"
# Honeypot — treat as success upstream; caller checks separately.
website = data.get("website", "")
if isinstance(website, str) and website.strip():
return "honeypot"
# Accept legacy "website" (autofill magnets) and current "hp_company".
for pot in ("hp_company", "website"):
raw_pot = data.get(pot, "")
if isinstance(raw_pot, str) and raw_pot.strip():
return "honeypot"
def field(key: str, max_len: int) -> str | None:
raw = data.get(key, "")

View file

@ -429,8 +429,8 @@
<form id="contactForm" data-status-loading="..." data-status-success="Sent ✓" data-status-error="Could not send. Please try again.">
<label class="hp-field" aria-hidden="true">
<span>Website</span>
<input type="text" name="website" tabindex="-1" autocomplete="off">
<span>Company fax</span>
<input type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
</label>
<label>

View file

@ -278,8 +278,8 @@
<form id="contactForm" data-status-loading="..." data-status-success="Sent ✓" data-status-error="Could not send. Please try again.">
<label class="hp-field" aria-hidden="true">
<span>Website</span>
<input type="text" name="website" tabindex="-1" autocomplete="off">
<span>Company fax</span>
<input type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
</label>
<label>

View file

@ -429,8 +429,8 @@
<form id="contactForm" data-status-loading="..." data-status-success="Отправлено ✓" data-status-error="Не удалось отправить. Попробуйте ещё раз.">
<label class="hp-field" aria-hidden="true">
<span>Website</span>
<input type="text" name="website" tabindex="-1" autocomplete="off">
<span>Company fax</span>
<input type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
</label>
<label>

View file

@ -334,8 +334,8 @@
<form id="contactForm" data-status-loading="{{FORM_STATUS_LOADING}}" data-status-success="{{FORM_STATUS_SUCCESS}}" data-status-error="{{FORM_STATUS_ERROR}}">
<label class="hp-field" aria-hidden="true">
<span>Website</span>
<input type="text" name="website" tabindex="-1" autocomplete="off">
<span>Company fax</span>
<input type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
</label>
<label>

View file

@ -183,8 +183,8 @@
<form id="contactForm" data-status-loading="{{FORM_STATUS_LOADING}}" data-status-success="{{FORM_STATUS_SUCCESS}}" data-status-error="{{FORM_STATUS_ERROR}}">
<label class="hp-field" aria-hidden="true">
<span>Website</span>
<input type="text" name="website" tabindex="-1" autocomplete="off">
<span>Company fax</span>
<input type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
</label>
<label>

View file

@ -441,8 +441,18 @@ a:hover{opacity:0.7;}
}
#contactForm label{display:block; margin-bottom:20px; font-size:13px; color:var(--text);}
#contactForm .hp-field{
position:absolute; left:-10000px; top:auto; width:1px; height:1px;
overflow:hidden; opacity:0; pointer-events:none;
position:absolute !important;
left:-10000px !important;
top:auto !important;
width:1px !important;
height:1px !important;
margin:0 !important;
padding:0 !important;
overflow:hidden !important;
clip:rect(0,0,0,0) !important;
border:0 !important;
opacity:0 !important;
pointer-events:none !important;
}
#contactForm input, #contactForm textarea{
width:100%; margin-top:6px; padding:10px; border:1px solid var(--border);

View file

@ -278,8 +278,8 @@
<form id="contactForm" data-status-loading="..." data-status-success="Отправлено ✓" data-status-error="Не удалось отправить. Попробуйте ещё раз.">
<label class="hp-field" aria-hidden="true">
<span>Website</span>
<input type="text" name="website" tabindex="-1" autocomplete="off">
<span>Company fax</span>
<input type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
</label>
<label>

View file

@ -429,8 +429,8 @@
<form id="contactForm" data-status-loading="..." data-status-success="Надіслано ✓" data-status-error="Не вдалося надіслати. Спробуйте ще раз.">
<label class="hp-field" aria-hidden="true">
<span>Website</span>
<input type="text" name="website" tabindex="-1" autocomplete="off">
<span>Company fax</span>
<input type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
</label>
<label>

View file

@ -278,8 +278,8 @@
<form id="contactForm" data-status-loading="..." data-status-success="Надіслано ✓" data-status-error="Не вдалося надіслати. Спробуйте ще раз.">
<label class="hp-field" aria-hidden="true">
<span>Website</span>
<input type="text" name="website" tabindex="-1" autocomplete="off">
<span>Company fax</span>
<input type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
</label>
<label>