Thousands of domain names still have improperly configured SPF records
Yeah, you read it right. It is 2022, and people still don’t know how to configure the Sender Policy Framework record for their domain names. For those who don’t know, SPF is an authentication mechanism standardized in April 2014, which makes it possible to verify the sender of an email. The verification procedure is pretty simple: the receiving side looks up the SPF record of the sender’s domain name and determines if the originating IP address is allowed to send an email on behalf of that domain.
The SPF record looks something like this:
v=spf1 ip4:213.202.123.0/24 include:spf.protection.outlook.com -all
As you can probably see, the record is composed of multiple parts:
- “v=spf1”, denoting the SPF record, can be incremented in future iterations of protocol,
- “ip4”, indicating IPv4 subnet(s) in CIDR notation, can also be “ip6” for IPv6,
- “include” mechanism designating administratively independent domain(s) - optional,
- "-all" mechanism commanding the recipient’s mail server to discard any email from IP addresses not listed in the record.
So, SPF might be very useful in preventing impersonation, phishing, and spam. Unfortunately, SPF can’t help you if you allow billions of IP addresses to send emails on behalf of your domain name with an overly permissive SPF record. After seeing an article on WeLiveSecurity, I decided to check some of the most popular gTLDs (.com, .net, and .org) to see which amount of domains are allowing my IP address to pass the SPF.
The easiest way to achieve this was by using the pyspf package. I already knew that most of the gTLDs publish the list of domain names in CZDS and had access to it, so it was only a matter of parsing the zone files and extracting each domain to the zone-corresponding textual file. I would later use the extracted domains in my multithreaded scanner and output those with improperly configured SPF records to another textual file. The cheapest and most effective method for me was splitting the extracted domains into chunks of 5 million and running each chunk on one OVHcloud d2-8 instance. In total, I scanned about 159 million .com, 13 million .net, and 15 million .org domain names.
Some of the gTLDs with improperly configured SPF records include:
.com:
- darude.com - Finnish DJ and record producer,
- ubuntu.com - a Linux distribution based on Debian.
.net:
- sumoforum.net - an old and popular forum,
- torservers.net - a global network of non-profits running Tor relays.
.org:
- gadnr.org - Georgia Department of Natural Resources,
- iemed.org - European Institute of the Mediterranean,
- jpeg.org - The Joint Photographic Experts Group (JPEG) committee,
- nln.org - National League for Nursing.
Besides the commonly used gTLDs, almost every sovereign country has its own ccTLD. Particularly, I was interested in looking up regional ccTLDs (.ba, .hr, .me, .mk, .rs and .si) and commonly used ccTLDs (.ai, .co, .fm, .io, .to and .tv). Many ccTLDs opt not to publish their zone file publicly, so I needed to find a different way to obtain a list of domain names to scan. Fortunately, I found DNS Census 2013 and DomCop top ten million websites.
Some of the ccTLDs with improperly configured SPF records include:
.ai:
- active.ai - a service platform that connects consumers with their banks via micro conversation ($14.8M in funding according to Crunchbase),
- browse.ai - web automation software that records actions on a website and then runs them on the cloud without any code (pre-seed).
.ba:
- coca-cola.ba - Coca-Cola BiH,
- elta-mt.ba - ELTA-MT cable operator,
- jpdcfbh.ba - Roads of the Federation of Bosnia and Herzegovina,
- txtv.ba - TXTV cable operator.
.io:
- kubegres.io - open source Kubernetes operator allowing to deploy a cluster of PostgreSQL instances with data replication enabled out-of-the-box (reported here, fixed),
- tabler-icons.io - popular open source icon set (reported here, fixed).
.me:
- after.me - a platform to assist people in creating their hassle-free and free-of-cost text or video testament,
- survol.me - a browser extension to preview hovered links (reported here).
.mk:
- bsv.gov.mk - Bureau for Court Expertise,
- komspi.mk - The Agency for Protection of the Right to Free Access to Public Information,
- mepso.com.mk - MEPSO Electricity Transmission System Operator (state-owned),
- tetovo.gov.mk - Municipality of Tetovo.
.rs:
- nub.rs - National and University Library of the Republic of Srpska,
- salva.rs - 2D and 3D fluids simulation engine for the Rust programming language (reported here).
.si:
- emm.si - EMN European Migration Network,
- ernstyoung.si & ey.si - multinational professional services company.
While scanning, I also discovered a bug in the pyspf library, which encountered an unhandled exception while checking openprocurement.io, and reported an issue to the project’s GitHub repository.
I’m pretty surprised with the overall number of domain names with improperly configured SPF records. This potentially devastating issue which could aid the business email compromise attacks is present amongst domains belonging to many corporate, governmental, and NGO entities. When creating SPF records, it is imperative to use narrow subnets and limit the scope of IP addresses that could send an email on behalf of your domains. Besides that, as there is no point in using always match (+all) or neutral (?all) mechanisms, mail-receiving servers should treat domain names with those mechanisms as those without an SPF record.
A list of all domain names with misconfigured SPF records is available here. Special thanks to Open PageRank for providing PageRank data.