We checked 71 clinic websites for email spoofing protection. Then we found the same hole in our own domain
Clinics hold the most sensitive data there is: diagnoses, test results, appointments. Patients trust emails that come from their clinic's domain. So we asked a simple question: can anyone send an email that looks like it
Clinics hold the most sensitive data there is: diagnoses, test results, appointments. Patients trust emails that come from their clinic's domain. So we asked a simple question: can anyone send an email that looks like it came from a private clinic?
We checked 71 private clinic websites in Lviv, Ukraine, in October 2026. Passive checks only: the home page, HTTP headers and public DNS records, exactly what any visitor or mail server sees. No scanning, no login attempts. We publish aggregate numbers only, no clinic names.
The result
Not one of the 71 domains has DMARC set to block spoofed email.
- 79% have no DMARC record at all.
- The rest have
p=none, which only monitors and blocks nothing.
For a patient, that means a fraudster can send "your test results are attached" or "pay for your appointment here" from the clinic's real address, and the inbox will not flag it.
Other findings from the same scan:
- 80% send no HSTS header.
- 89% have no Content-Security-Policy.
- 15% load jQuery older than 3.5, which has known XSS issues.
- 83% have images with no alt text; 31% of all images are undescribed.
The good news: all 71 use HTTPS and are mobile-friendly. The basics are there; the next step is missing.
Then we checked ourselves
Our studio domain, olbo.com.ua, had SPF and DKIM configured properly, and DMARC set to... p=none. Exactly the gap we had just written about.
SPF, DKIM, DMARC in one paragraph each
SPF is a TXT record on your domain listing who may send mail for it:
v=spf1 include:zohomail.eu ~all
DKIM is a signature on every message. Your mail provider signs with a private key; receivers verify with the public key published at selector._domainkey.yourdomain.
DMARC tells receivers what to do when a message fails the checks, and where to send reports:
_dmarc.yourdomain TXT "v=DMARC1; p=quarantine; rua=mailto:reports@yourdomain"
p=none = report only. p=quarantine = spam folder. p=reject = don't deliver. Only the last two actually protect anyone.
How we switched without breaking our own mail
The risk with p=quarantine is that your legitimate mail starts landing in spam. The usual culprit is a service you forgot sends mail as you: a contact form, a newsletter tool, a CRM, an invoicing system.
Our list was short:
-
Zoho Mail for people (hello@). DKIM key
zmail._domainkey, included in SPF. -
Resend for the website: form notifications and report emails, sent as forms@. DKIM key
resend._domainkey; the return path is on a subdomain, which still aligns under DMARC's default relaxed mode.
Both already had DKIM, so the change was one edit: p=none → p=quarantine.
Then we verified with real messages, not just DNS lookups:
- An email from hello@ to a Gmail inbox → "Show original": SPF PASS, DKIM PASS, DMARC PASS.
- A website form submission → arrived, not in spam.
- An automated report email sent through Resend → SPF, DKIM, DMARC: PASS.
Total time: about 10 minutes. We'll move to p=reject in 2–3 weeks after reading the aggregate reports.
Checking a domain yourself
From a terminal:
dig +short TXT yourdomain.com | grep spf1
dig +short TXT _dmarc.yourdomain.com
Or in Node, which is roughly what our checker does:
import { promises as dns } from 'node:dns'
const txt = async (name) => {
try { return (await dns.resolveTxt(name)).map((r) => r.join('')) }
catch { return [] }
}
const domain = 'example.com'
const spf = (await txt(domain)).find((r) => r.startsWith('v=spf1'))
const dmarc = (await txt(`_dmarc.${domain}`)).find((r) => /^v=DMARC1/i.test(r))
const policy = dmarc?.match(/\bp=(\w+)/i)?.[1]?.toLowerCase()
console.log({ spf, dmarc, protected: !!spf && ['quarantine', 'reject'].includes(policy) })
Note the join(''): long TXT records come back split into 255-byte chunks.
If you'd rather not open a terminal, or want to send something to a non-technical client, we made the same check into a free page with a plain-language answer and no sign-up: olbo.com.ua/en/dmarc-checker. We don't store the domains people enter.
Takeaway
If you build sites for small businesses, add one line to your handover checklist: "DMARC at quarantine or reject, tested with a real email." It's an hour of work and closes one of the easiest ways to impersonate your client.
The full clinic study, including the four steps we recommend to clinic managers, is here: Clinic website security: a study of 71 clinic sites.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.