Open desh-se opened 7 years ago
SPF_MAX_MECH_LEN is 511, which IMHO is a bit draconian considering that RFC 7208 only gives a SHOULD requirement for the maximum record size limit of 512 (paragraph 3.4).
In any case the Neutral result is wrong. There is a paragraph about processing limits (11.1), alas it doesn't say specifically what should be returned in response to long records, but I think that PermError would be the best choice.
I would suggest something like #22 to fail harder. However, this only fixes half the issue.
Should libspf2 also raise or double these limits, and how does that affect other buffers like?
https://github.com/shevek/libspf2/blob/master/src/libspf2/spf_compile.c#L62
We fixed this in our code by adding a value for the maximum number of mechanisms and not looking at the total length. See the attached patch. spf_compile.c.patch.txt
This is what I see:
>unbound-host -rvD -tTXT unilever.com | grep spf
unilever.com has TXT record "v=spf1 include:spf.protection.outlook.com " "ip4:204.14.232.0/25 ip4:174.143.99.125 ip4:67.192.157.83 ip4:134.213.38.184/31 ip4:134.213.43.128 ip4:156.51.31.71 ip4:162.61.224.50 ip4:213.177.33.153 ip4:89.234.41.53 " "ip4:160.34.64.0/23 ip4:208.185.229.40/29 ip4:208.185.235.40/29 ip4:208.185.229.197 ip4:208.185.229.198 ip4:208.185.229.199 ip4:208.185.235.197 ip4:208.185.235.198 ip4:208.185.235.199 " "ip4:13.112.93.182 ip4:54.178.172.43 ip4:62.128.223.55 ip4:199.255.192.0/22 ip4:199.127.232.0/22 ip4:54.240.0.0/18 ip4:213.129.90.104 ip4:84.45.15.6 ip4:188.95.0.38 ip4:188.95.7.6 " "ip4:89.202.116.58 ip4:80.253.212.192/27 ip4:194.4.230.64/27 ip4:205.223.230.229 ip4:62.6.153.165 ip4:208.92.178.200 ip4:208.92.176.200 " "ip4:208.92.177.152 ip4:54.229.2.165 ip4:54.153.131.110 ip4:52.1.14.157 ip4:52.30.130.201 ip4:54.66.252.242 ip4:52.17.45.98 ip4:54.173.83.138 ip4:52.16.190.81 ip4:212.247.0.242/31 " "ip4:194.204.27.131 ip4:194.204.0.4 ip4:82.199.250.65 ip4:176.74.168.123 ip4:113.192.243.106/31 ip4:212.72.39.68 ip4:212.72.39.197 ip4:217.17.192.101 " "ip4:50.56.7.39 ip4:185.136.189.88 ip4:185.136.188.88 ip4:134.213.173.64/28 ip4:162.61.252.6 ip4:162.61.252.7 ip4:162.61.252.27 ip4:43.228.187.74 ip4:141.146.165.0/27 ip4:64.181.217.128/27 " "a:b.spf.service-now.com a:c.spf.service-now.com a:d.spf.service-now.com ip4:162.61.254.53 ip4:162.61.254.54/31 ip4:162.61.254.56/30 ip4:162.61.254.60 -all" (insecure)
>spfquery -ip 162.61.254.60 -sender unilever.com
neutral
Please see http://www.openspf.org/Why?id=postmaster%40unilever.com&ip=162.61.254.60&receiver=spfquery : Reason: default
spfquery: 162.61.254.60 is neither permitted nor denied by domain of unilever.com
Received-SPF: neutral (spfquery: 162.61.254.60 is neither permitted nor denied by domain of unilever.com) client-ip=162.61.254.60; envelope-from=postmaster@unilever.com;
It is not true that the given IP "is neither permitted nor denied by" the SPF policy, so the use of "neutral" is a violation of RFC 7208 section 2.6.2 and thus a bug. Patching it with "fail" would be a violation of section 2.6.4.
In the absence of EDNS0 any DNS response which exceeds 512 bytes signals truncation and prompts a retry via TCP. So it is desirable to keep TXT SPF RR within the limit, for compatibility with older systems, but unilever.com seems to be EDNS0 compliant where this limit does not apply. The hard limit for RRs is 65535 bytes by RFC 882, and unilever's record is 3x512 bytes shy.
The response should rather be fair to the fact that the RR exceeded the recommended length of 512 bytes. However, since the DNS response reached the SPF validator, and the IP is clearly authorised by the SPF policy, then the correct response should be "pass".
The patch by heyyoucb helps, but I am not sure it is the definite patch to this bug.
This is what I see with the patched spf_compile.c:
>spfquery -ip 162.61.254.60 -sender unilever.com
pass
spfquery: domain of unilever.com designates 162.61.254.60 as permitted sender
Received-SPF: pass (spfquery: domain of unilever.com designates 162.61.254.60 as permitted sender) client-ip=162.61.254.60; envelope-from=postmaster@unilever.com;
Not sure this is relevant, but looking at this today, I noticed that on glibc it appears not to find a match for 162.61.254.60 which still is in the spf record, but on musl it doesn't get any further than the first 9 TXT entries, never finding the spf record. The glibc case seems to be that the patch referred to here once addressed -- the code changed howver -- the second is a whole different problem that libspf can only solve by not using req_query, but something else to do resolving.
We've noticed a few domains which have longer SPF records than what libspf2 support. One such example is unilever.com:
The limit seems to be
SPF_MAX_MECH_LEN
, which triggersSPF_E_BIG_MECH
, which is ignored and thus results in aneutral
result.