Blog · Dmarc

How Safe Sender Lists Override DMARC p=reject (And What To Do About It)

The short answer

Yes. A safe sender list or transport rule exclusion can override DMARC p=reject enforcement at most email gateways. When a domain is on that list, the gateway skips authentication checks for that domain -- even when the domain has a published p=reject policy. No error is logged. No failure is flagged. The email lands in the inbox.

This is not a bug. It is a design trade-off that made sense when email gateways were simpler and vendor relationships were more trusted. It makes less sense now that email security vendors have been breached and their platforms abused to bypass authentication.

Why it happens

Most enterprise email gateways assign a Spam Confidence Level (SCL) to each inbound message. A low or negative SCL -- typically SCL -1 -- tells the gateway to skip most filtering, including authentication checks. Safe sender lists and transport rule exclusions often apply this bypass by design: the assumption is that trusted senders should not be delayed or filtered.

The problem is that DMARC authentication runs before the SCL override is applied in many gateway architectures. When the override is evaluated first, the message is released from further checks. SPF, DKIM, and DMARC alignment are never evaluated against the sending domain's published policy.

In practice, this means allow-list entries function as authentication bypass rules, whether or not that was the intent.

The Greatness phishing kit case

This mechanism was observed in the wild with the Greatness phishing kit, documented by Abnormal Security in 2022. Attackers sent email that failed both SPF and DKIM against the RingCentral domain. The targeted organization had RingCentral on a safe sender list in their email gateway. The gateway evaluated the allow-list entry before DMARC, assigned SCL -1, and the message bypassed authentication and arrived in the inbox.

The same pattern applies to any vendor or partner domain on your allow-list.

Why the trade-off is riskier now

The original logic: we trust this vendor, we do not want their notifications flagged as spam, so we allow-list them. Reasonable when email security meant controlling spam and vendor platforms were not common breach targets.

Both assumptions have degraded. Email security vendors have been compromised and their platforms used as authentication bypass conduits. An attacker who compromises a vendor's platform, or who finds a misconfigured allow-list entry, can send as any domain your gateway trusts. Your DMARC p=reject policy will not protect you against that.

The gap is concrete: your DMARC is at p=reject except for the vendor domains on your allow-list.

How to audit your gateway allow-list configuration

Run this audit across your email gateway or proxy:

1. Export all safe sender list entries and transport rule exclusions that apply to external domains.
2. For each entry, check whether the domain publishes a DMARC policy.
3. For domains publishing p=reject or p=quarantine, flag the entry as a potential authentication bypass.
4. Ask whether each allow-list entry is still necessary. Some will be. Many will not be.
5. For exceptions that remain, document them as known bypass points and review quarterly.

A practical tool for this step: DMARCFlow aggregate reports show you authentication failures by sending domain. If a domain on your allow-list publishes p=reject and your reports show regular failures from IPs you do not recognize, that is a mismatch worth investigating. Running this check across all your monitored domains takes minutes instead of hours of manual reconciliation.

Without recurring review, the allow-list grows and your effective DMARC coverage shrinks.

How to harden without breaking vendor email

Prefer per-mailbox allow-lists over global ones. A global allow-list for a vendor domain means every mailbox trusts that domain unconditionally. Per-mailbox entries limit exposure.

Use envelope sender or header-based rules instead of domain-level allow-lists. If the vendor sends from a consistent envelope sender domain or you can match on a specific header, that is a narrower trust boundary than the entire visible From domain.

Require DKIM pass for allow-listed domains where possible. Some gateways let you allow-list a domain but still verify DKIM. That preserves the monitoring benefit of your DMARC policy for those domains.

Monitor DMARC aggregate reports for allow-listed domains. If a trusted domain publishes p=reject but your reports show regular failures from unexpected IPs, something may have changed -- on the vendor side or in your own configuration.

FAQ

Can a safe sender list actually override DMARC p=reject?
Yes. At most enterprise email gateways, a safe sender list or transport rule exclusion that matches an inbound message causes authentication checks to be skipped. DMARC policy is not evaluated. This is documented behavior, not an error.

Does this mean DMARC p=reject is useless?
No. DMARC p=reject protects against impersonation from sources not on your allow-list. It also protects against vendors you have not explicitly exempted. The gap is specific to domains you have chosen to trust in your gateway configuration.

Is this only a problem with Microsoft Exchange?
No. The SCL -1 bypass mechanism has been documented across Exchange Online Protection, third-party secure email gateways, and on-premises appliances. The pattern is widespread; the specific configuration steps vary by platform.

How do I find all my allow-list entries?
In Exchange Online, use Get-HostedContentFilterPolicy and Get-TransportRule. For third-party gateways, the configuration UI usually has a separate section for safe sender lists and IP allow-lists. Export everything -- do not rely on the UI showing you the complete picture.

Should I remove all allow-list entries?
No. Some vendors cannot send email that passes DMARC without changes to their own infrastructure. Removing those entries breaks legitimate communication. Audit each entry, reduce the scope where possible, and document the exceptions.

---

Related: DMARC p=none vs p=reject: When to Move Your Policy Up