SPF permerror with +all

I thought I understood how SPF works, but I found something today that makes me question my assumptions. I think I know what's actually going on, but I'm hoping someone out there will be able to tell me for certain.

One of my associates had a syntax error in their SPF record, which was causing it to be ignored entirely. I suggested they fix it, which they did. But now they've changed it so that, after specifying a number of includes, etc. it ends in +all. Here's the actual (modified) record they set up:

v=spf1 a mx ptr include:_spf.google.com include:xxxx.com include:yyyy.com include:zzzz.net +all

Now, to my understanding this reads, this could effectively be shortened to: v=spf1 +all, since +all means "allow anything else." This would be bad. Worse, in fact, than having no SPF record at all. And I was preparing to tell them so, but I wanted to test it first a) just to make sure my understanding was correct, and b) to have something to show them, which would demonstrate why it was so bad.

To do this, I went to www.deadfake.com - a site that allows you to spoof mail. I entered my email address as the To, and an address at their domain as the From, and sent the message. My expectation was that it would show up in my email box, having passed the SPF filters without a problem.

But that's not what happened. Instead, I found it in my junkmail folder with the following notice in the mail header:
Authentication-Results: spf=permerror (sender IP is x.x.x.x)
 smtp.mailfrom=theirdomain.com; mydomain.com; dkim=none (message not signed)

Now this puzzled me because the +all should have permitted it, right?

Then I checked an email I received from the domain in question, after the SPF records had already been changed. This message got through just fine. When I checked the header there, I found this:
Authentication-Results: spf=pass (sender IP is y.y.y.y)
 smtp.mailfrom=theirdomain.com; mydomain.com; dkim=none (message not signed)

It didn't fail, and I don't understand why there's a difference.

But here's what I think is going on. Hopefully, someone can tell me if I'm right.

I'm guessing that, because +all is such a bonehead-stupid thing to put into an SPF record, some mail servers are rejecting them as if they were an actual error, even though that's technically against the spec. Now that doesn't mean ALL mail servers will do that, so it's still a bad thing to do. I'm also thinking that the SPF filter is functioning as a first-pass filter. In other words, it checks an incoming email against the filters specified in order, and the first one it passes, makes it a Pass. Since the one that actually came from their domain did pass one of the filter rules, it's showing up as a Pass.

Does that make sense? Or is there something else I'm missing?
LVL 8
David SpigelmanPresident / CEOAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DrDave242Senior Support EngineerCommented:
The problem is most likely one of the include mechanisms. If one of those refers to a domain that doesn't have a valid SPF record, permerror is the result, and even the +all at the end won't override a permerror.

See here for more info.

Also, you're correct: adding +all to the end of the SPF record basically renders everything else in the record moot, unless you're testing for errors.
DrDave242Senior Support EngineerCommented:
I'll clarify my previous comment a bit:

The mechanisms in an SPF record are processed in order, from left to right. As soon as a match is found or an exception (error) is encountered, processing ends, and the result is returned. Any subsequent mechanisms (including +all) are ignored.

Because of this, +all is not entirely useless. You could construct an SPF record that allows all hosts except for certain ones to send on behalf of your domain by using -mechanisms instead of +mechanisms. In that case, it would make sense to put +all at the end of the record. I can't think of a single practical reason to do that, however.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
David SpigelmanPresident / CEOAuthor Commented:
I see. Yeah, I guess you could, but you're right - it wouldn't make much sense.

Well, I just checked. All the includes do have SPF records. Most of them have their own includes that are redundant with the others (i.e. xxxx.com and yyyy.com and zzzz.com all have most of the same +ip4 filters), but they're there. One of them has a couple of includes of its own, and they also have valid SPF records.

So while your explanation makes sense as to why theirs passed, it still doesn't explain why the +all didn't pass the one from deadfake.com.
Active Protection takes the fight to cryptojacking

While there were several headline-grabbing ransomware attacks during in 2017, another big threat started appearing at the same time that didn’t get the same coverage – illicit cryptomining.

DrDave242Senior Support EngineerCommented:
I'll admit, I don't like includes, especially nested includes, as they're a pain to troubleshoot.

My best guess is that the IP used to send the real message from the customer's domain matched a mechanism in the record before it was parsed to the point of the error (and that match gave a PASS result), but the IP used to send from deadfake.com didn't, so the error was encountered. Without knowing the specific mechanisms in the record, though, that's just a guess.
David SpigelmanPresident / CEOAuthor Commented:
Well, it didn't sound right to me because everything seemed to pass, when I ran it through some of the web-based tools. (e.g. http://emailstuff.org, http://mxtoolbox.com, etc...) So I tested it. I changed the SPF record on one of MY domains so that it ended with a +all, to see whether it passed the SPF check. My SPF record for that domain was very light: Just Google's SPF include. Then I sent myself another message from Deadfake, expecting it to fail, thus proving me right.

But it passed the SPF check, just the way it is supposed to. Here's the mail header:
Authentication-Results: spf=pass (sender IP is x.x.x.x)
 smtp.mailfrom=myotherdomain.com; mymaindomain.com; dkim=none (message not signed)
So you're right. SPF is functioning properly, and there's still an error in their record, probably having to do with some of the nested includes, or the redundancy. Further research needed.

Thanks for helping me figure that out.
David SpigelmanPresident / CEOAuthor Commented:
Oh - just one point of clarification, as I re-read the thread. To your last point, I'm actually guessing that Deadfake doesn't fail an earlier mechanism, because there are no explicit rejects involved, and there's a +all at the end. I'm guessing that your earlier thought, that there's an error in at least one of the nested includes, is the culprit. It's the only thing that makes any sense.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
DNS

From novice to tech pro — start learning today.