← All posts
7 min readEric Smith

Five Days of Validin, Day 3: Can someone send email as you?

Ask a nonprofit what their biggest cyber risk is and they will say ransomware. Ask their insurer and they will say business email compromise. The insurer is right. The money leaves through the inbox far more often than through encrypted servers.

This is the most actionable day in the series. Everything else finds out what exists. Today you can turn on a control.

The command

curl -s -H "Authorization: Bearer $VALIDIN_KEY" "https://app.validin.com/api/axon/domain/dns/extra/symbolics.com?limit=250&time_format=iso"

In the web interface, search the domain and look at the TXT, MX, CAA, and CNAME record types.

This returns the record types Day 1 did not: MX, TXT, CAA, SOA, CNAME, SRV. With history, which turns out to be the most useful part.

What comes back

Real output, complete:

{
  "query_key": "symbolics.com",
  "status": "finished",
  "records": {
    "MX": [
      {"key": "symbolics.com", "value": "mail.symbolics.com", "value_type": "dom",
       "first_seen": "2023-05-18T00:00:00Z", "last_seen": "2026-08-10T00:00:00Z"}
    ],
    "SOA_MNAME": [
      {"key": "symbolics.com", "value": "primary.guardeddns.net", "value_type": "dom",
       "first_seen": "2023-05-18T00:00:00Z", "last_seen": "2026-08-09T18:00:00Z"}
    ],
    "SOA_RNAME": [
      {"key": "symbolics.com", "value": "dns-admin.guardeddns.net", "value_type": "dom",
       "first_seen": "2023-05-18T00:00:00Z", "last_seen": "2026-08-09T18:00:00Z"}
    ],
    "TXT": [
      {"key": "symbolics.com", "value": "v=spf1 a mx ip4:23.80.91.219 ~all",
       "value_type": "raw",
       "first_seen": "2026-04-04T12:00:00Z", "last_seen": "2026-08-09T18:00:00Z"},
      {"key": "symbolics.com", "value": "v=spf1 a mx ip4:64.255.46.14 ~all",
       "value_type": "raw",
       "first_seen": "2023-05-18T00:00:00Z", "last_seen": "2026-03-28T00:00:00Z"}
    ]
  },
  "records_returned": 5,
  "limited": false
}

Records are grouped by type, and time_format=iso does work on this endpoint.

Four things to check

1. SPF, and the maintenance trap inside it

Find the TXT record starting with v=spf1. It lists who may send mail as the domain. What matters is the end.

-all rejects anything from a server not on the list. This is what you want.

~all is a soft fail: treat as suspicious, probably deliver anyway. Most organizations stop here because it feels safer.

?all expresses no opinion and is equivalent to having no SPF.

Both records above end in ~all, which is the most common configuration on the internet and the reason forged mail so often still gets delivered.

Now look at what changed between them:

v=spf1 a mx ip4:64.255.46.14 ~all     (2023-05 to 2026-03)
v=spf1 a mx ip4:23.80.91.219 ~all     (2026-04 onward)

a and mx are self-maintaining. They mean “whatever address this domain resolves to” and “whatever the MX records point at,” so they follow your infrastructure automatically.

ip4: does not. It is a hardcoded address, and it is only correct until the day your mail server moves.

Here that entry was updated in April 2026, which means somebody was paying attention. That is the exception, not the rule.

The most common serious flaw I find in nonprofit DNS is an ip4: entry pointing at infrastructure the organization abandoned years ago. Cloud providers recycle addresses constantly. When they do, whoever receives that address inherits your explicit permission to send email as your domain, and nothing anywhere will warn you.

Go read your own SPF record right now for bare ip4: or ip6: entries. For each one, answer a single question: do I still control that address? If you cannot answer confidently, that is your afternoon.

I ran this against my own domain while preparing the series and found exactly that: an ip4: authorizing an AWS address I stopped using in 2023. I write about this for a living and I still had one.

Before tightening to -all, inventory every system that sends as your domain: mail platform, CRM, donation processor, email marketing, ticketing. Tightening with an incomplete list bounces legitimate mail, and the first casualty is usually your newsletter.

2. DMARC, and an important caveat

DMARC lives on a subdomain, so query it separately:

curl -s -H "Authorization: Bearer $VALIDIN_KEY" "https://app.validin.com/api/axon/domain/dns/extra/_dmarc.yournonprofit.org?limit=250&time_format=iso"

An empty result does not prove you have no DMARC record. This one catches people, so it is worth being precise.

Validin is passive. It reports what has been observed, and a _dmarc TXT record is only observed when something queries it. A domain sending little mail may have a perfectly good DMARC record that no collection point has ever seen. When I ran this against my own domain it returned zero records, which told me nothing conclusive.

Treat empty as “unknown,” not “missing,” and confirm authoritatively:

dig +short TXT _dmarc.yournonprofit.org

That asks DNS directly. The distinction matters, because publishing a DMARC record when one already exists, and assuming you are unprotected when you are not, both lead somewhere bad.

When you find one, the policy field is what counts. p=none monitors only. p=quarantine sends suspected forgeries to spam. p=reject refuses them.

The right path is p=none with a reporting address first, so you can see what actually sends as your domain, then tighten. Skipping the monitoring step is how organizations block their own mail.

3. MX

Check they point where you think.

symbolics.com has a single MX at mail.symbolics.com, which means self-hosted mail on its own infrastructure. That was universal in 1985 and is unusual now, when most small organizations point their MX at Google or Microsoft.

Look for records pointing at a provider you stopped using, which sometimes still receive mail, and unfamiliar hostnames that occasionally indicate a forwarding rule set up years ago and forgotten.

4. CAA

Not email, but it belongs in the same fifteen minutes.

A CAA record tells certificate authorities which of them may issue for your domain. The output above contains none, which is the common case and means any CA in the world will issue for that domain if someone proves control.

Adding one that names only the CA you use closes that off. It is a single line, and it pairs directly with the wildcard certificate problem from Day 2.

The stale records nobody removes

While you are in your TXT records, look for verification tokens.

Services prove domain ownership during setup by asking you to publish a string like MS=ms47121196 or google-site-verification=.... They serve no purpose afterward. On my own domain I found a Microsoft verification token still sitting there years after the mail moved to Google Workspace.

Leaving them is minor, but it is exactly the kind of thing that should not outlive its purpose, and in some tenant scenarios a stale verification record can be re-used. Scan for verification strings from services you no longer use. Removing them is housekeeping, and housekeeping is most of security at a small organization.

What a bad result looks like

The common combination at a small nonprofit: no DMARC, an SPF record ending in ~all written years ago that does not list the current mail platform and does contain a stale ip4:, no CAA, and two or three abandoned verification tokens.

That means a forged message from your domain will usually be delivered, you will have no report telling you it happened, and the first you hear is a donor asking why you sent them a strange invoice.

What to do about it

Order of operations that avoids breaking things:

Inventory your senders. Confirm your current records with dig. Publish DMARC at p=none with a reporting address. Watch the reports for a few weeks. Correct your SPF based on what you learn, removing any ip4: entry you cannot vouch for. Then tighten SPF to -all and DMARC to quarantine, and later reject.

Add the CAA record whenever. It has no dependency on the rest. Delete the stale verification tokens while you are in there.

Why this one matters more than it looks

For an organization where one fraudulent wire transfer is a program shutting down, this is the highest-value fifteen minutes in the series.

And unlike most security advice, it is entirely within your control. No vendor to persuade, no budget request. Text records at your DNS provider.

That is five queries out of your fifty.

Tomorrow, Day 4: the four-minute answer when a staff member forwards you a suspicious email.