The Securing Government Services team at the Central Digital and Data Office recently encountered, and fixed, a small bug with the way some government domains handle their Sender Policy Framework (SPF) records.
SPF allows a domain owner to specify which email services are authorised to send email on their behalf. For example, the website example.gov.uk might use Outlook for email - so they can create a TXT record in their DNS which says:
<span style="font-weight: 400">"v=spf1 include:spf.protection.outlook.com -all"</span>
This tells the internet that if someone tries to send an email purporting to come from example.gov.uk, it will only be valid if it has been sent from the Outlook server. If it comes from a different server, it must be rejected.
This prevents people from sending spoofed emails which impersonate legitimate government services.
SPF records need to be written in a precise format. If the syntax is even slightly different from the specification, the record is invalid and spoofed emails will be able to be delivered.
Discovering the problem
Our team recently noticed a record which was syntactically correct - but was, somehow, still being marked as invalid. This was a serious risk and could have let a malicious actor send emails as though they were from a specific government service.
The SPF record looked like this:
<span style="font-weight: 400">"v=spf1 include:example.com include:spfprotectionoutlook.com -all"</span>
The SPF checker works on multiple levels. The first is a simple conformance check - that is, seeing if the record is written in the correct syntax. This record was correct.
The second level is to evaluate the included domains. This involves doing a DNS lookup on the domain. And this is where the problem was.
The second domain was misspelt. When a lookup was performed on that domain, it returned an error - NXDOMAIN.
Because this recursive check failed, it resulted in what the specification calls a "permerror" - which means the domain's published records could not be correctly interpreted.
Even though the record has the correct syntax, and even though other included domains validated correctly, because a single domain didn't exist the entire SPF record failed validation.
The specification is complicated and we had initially expected that a partially matching set of includes would still validate and the SPF would be valid. A thorough reading of the specification shows that is not the case.
Fixing the issue and lessons learned
The issue was fixed by correcting the spelling of the incorrect domain. We do not believe this error was actively exploited by malicious parties.
We learned several lessons from this incident:
- Domain names in SPF records need to be regularly audited. Domain names can be misspelt or expire - so they will need to be updated.
- The failure mode of SPF can be unexpected. It’s only one tool which can be used to reduce spoofed emails.
- Different mail servers can interpret an SPF permerror differently. Just because one mail system rejects the SPF record, that does not mean all of them will.
For more information, you can read our guidance on how to set up government email services securely.