-
Notifications
You must be signed in to change notification settings - Fork 332
Description
Prerequisites
- This issue has an informative and human-readable title.
💡 Summary
If multiple DMARC records are returned for a domain, the DMARC controls in the EXO baseline should fail.
Motivation and context
A single DNS query can return multiple answers. The DMARC RFC defines a policy discovery algorithm that we should be following. At a high level, it goes like this:
- Request the TXT records for the domain matching the FROM address.
- Ignore TXT records that don't start with
v=DMARC1; - If no DMARC record found, request the TXT records for the organizational domain
- Ignore TXT records that don't start with
v=DMARC1; - If no DMARC records are found or if multiple are found, stop processing DMARC.
ScubaGear almost follows that algorithm. However, it doesn't ensure that there aren't multiple DMARC records. If multiple are found, the DMARC controls should fail, to match what would happen when an actual MTA attempts to process their DMARC record.
Implementation notes
Consider this Rego code for the EXO baseline:
The simplest solution would be to change count(ValidAnswers) == 0 to count(ValidAnswers) != 1.
That would fix MS.EXO.4.1v1, but a few other changes would be needed for the other DMARC controls. For example, consider 4.2:

As is, a domain could still pass 4.2 with multiple DMARC records. Haven't tested, but something like this paired with the above change might do the trick:
DomainsWithoutPreject contains DmarcRecord.domain if {
some DmarcRecord in input.dmarc_records
ValidAnswers := [Answer | some Answer in DmarcRecord.rdata; contains(Answer, "p=reject;")]
true in [
DmarcRecord.domain in DomainsWithoutDmarc,
count(ValidAnswers) == 0
]
}
Acceptance criteria
ScubaGear fails the DMARC controls from the EXO baselines for domains that have multiple DMARC records.