Treating a prober as a customer

Look at an unauthenticated write endpoint — a form that sends mail — and you will usually find one problem being discussed and another being missed. The first is abuse: someone finds the URL and uses your endpoint to send things. The second is measurement: every probe of that endpoint looks, in your own numbers, like a person who wanted to reach you.

The second problem survives fixing the first.

Where the credential lives decides who can use the endpoint

The site is a static Jekyll build, so the POST goes to /contact/submit, which Caddy proxies to a small loopback-only listener that relays over the mesh to the fleet’s mail host. The endpoint requires a shared token, and a deploy step is where it becomes real:

1
2
3
4
# It is deliberately NOT baked into the site (the repo is public and
# the token must be rotatable without a rebuild): it is written here, at
# deploy time ... If the file is absent the endpoint stays locked and the
# form shows the visitor a mailto fallback rather than failing silently.

That last sentence is the design worth copying. An absent secret is a fail-closed condition: no token is published, the endpoint rejects everything with 403, and the page still offers a working mailto link rather than a form that appears to work and loses the message.

Rejections should be cheap, and ordered

pkgs/contact-form/contact_form.py states its ordering as a design constraint, and the ordering is the argument: method, content type, content length and rate limit are checked before any parsing, and parsing is capped before any SMTP connection is attempted.

The token is a header the page’s JavaScript sets, not a form field, so it is not part of a plain form POST, and it is compared with hmac.compare_digest. One line in the file is the decision most endpoints get backwards:

1
2
3
# Only an authenticated caller consumes rate-limit budget: the limit is
# there to bound a visitor (or a token-scraper), not to let unauthenticated
# probes lock out real submissions.

A rate limit any anonymous request can spend is a denial-of-service primitive aimed at your own visitors; here the cheap rejections never touch the budget.

A form in a comment still passes a naive check

The site also ships a gate, scripts/check-contact-form-visible.sh, and its header names the mistake it exists to catch: a grep for <form passes even when the markup sits inside an HTML comment. So it verifies the way a browser renders — it strips <!-- ... --> pairs, then asserts that id="ymrtech-form" and the controls name, email, message and website are all in the visible remainder, and that a stray opener has not swallowed the page.

That is the same lesson as the status claims elsewhere on this site: the audit page is built from signed artifacts for the same reason — check the artifact in the state it is actually in.

The half that survives the fix

Now the measurement half. A 403 from a token-less prober and a 200 from a real visitor are both one line against /contact/submit. If the number you watch is derived from paths, your funnel counts attackers as demand — and unlike the spam, that does not stop when the endpoint gets better.

So:

The asymmetry: you can reduce spam and clean up your metrics, but a public unauthenticated endpoint will keep receiving some non-human traffic. The useful goal is not zero — it is that none of it contaminates a decision. The same trap is in a test request is a real request: an observation made from the wrong position is evidence about the position.

What you can check

For how a missing token and a missing log line are recorded as evidence rather than assumed, see the logging stack and what no logs cannot promise.

󰔟 Running the same kind of stack?
The tunnel this site is written from is the one I sell: WireGuard to a gateway in Montréal, three DNS postures, one price — and the same "check it yourself" habit as everything above.
[ CREATE ACCOUNT ] [ WHAT IS THE VPN ]
󰣨 ymrtech@ymrtech | 󰌠 NixOS | 󰍢 UTF-8