CVE-2019-20790 - OpenDMARC through 1.3.2 and 1.4.x, when used with 
pypolicyd-spf 2.0.2, allows attacks that bypass SPF and DMARC 
authentication in situations where the HELO field is inconsistent 
with the MAIL FROM field.

Link: https://nvd.nist.gov/vuln/detail/CVE-2019-20790

Summary: opendmarc has added options to validate the Received-SPF: and 
spf-based Authentication-Results: headers as are added by some SPF 
validating implementations.

Details:

For the Received-SPF header field, opendmarc will not accept a result 
delivered via a discovered Received-SPF header field unless, in 
addition to stating "pass":

(a) it includes the "identity" key AND its value is "mailfrom", 

AND 

(b) it includes the "envelope-from" key AND its value matches the envelope 
sender that was passed via the milter protocol.  

AND

(c) per RFC 7208, that it is the topmost header field of its kind.

If any of those tests fails, a "pass" or a "fail" is interpreted 
as "neutral".  This is necessary to be compliant with RFC 7489 Section 4.1,
which says the SPF evaluation of MAIL FROM is what DMARC consumes.

For the Authentication-Results header field, in addition to requiring
a "spf=pass" key/value, we now require that:

(a) The smtp.mailfrom key be present

AND

(b) The domain portion of the value of the above key matches the 
envelope sender as above.  

Caveats:

Note carefully that many elements of both of the above header fields
that are relied upon for opendmarc to validate SPF processing by an 
earlier filter in the chain are not mandated by the RFC (they are listed)
as things tools SHOULD do, not MUST.

Some filters can set smtp.mailfrom=user@example.com, others can 
set smtp.mailfrom=example.com.  RFC 8601, which defines the
Authentication-Results header field allows both.  The opendmarc 
milter will only compare the "domain" portion of this value.

In fact, even the presence of a Received-SPF or Authentication-Results 
header field at all is not required to be added by a checking agent.

Admins are encouraged to carefully evaluate which header fields and
keys/values their milters add, and that it provides enough information
for opendmarc to make a decision.

Note that some mail filters may generate an SPF pass based on the
HELO result, which OpenDMARC will not accept.

This can result in the presence of a header which indicates that
SPF passed, but via an identity that DMARC does not consider, which
may be misleading to both users and admins.

Even if you are validating SPF earlier in your mail stream, for 
example to hard-reject mail from SPF-failing domains which set "-all",
you may wish to have OpenDMARC do its own SPF lookups, which
requires enabling at compile-time.  See the options "SPFIgnoreResults"
and "SPFSelfValidate" in either opendmarc.conf.sample or the
opendmarc.conf manpage.

