An authentication-failure report can be useful seconds after a message fails. It can also be a forged email carrying hostile MIME, a privacy-sensitive copy of somebody else's message, or the first packet in a denial-of-service campaign.
That combination makes ARF automation a security design problem, not just a parsing task. A safe system does not ask, "Does this message look like an ARF report?" It asks four separate questions:
The last question is the one most likely to be skipped. ARF fields are assertions made by the report generator. Even a well-formed report is not, by itself, proof that an authentication failure occurred.
RFC 5965 defines the Abuse Reporting Format as a MIME message with a top-level multipart/report content type and report-type=feedback-report. A normal report has three parts:
message/feedback-report machine-readable partmessage/rfc822 copy of the original message, or a text/rfc822-headers copy of its headersThe third part is evidence, not a trusted instruction. It may be redacted, incomplete, or maliciously constructed. The human-readable part is even less suitable for automation because it is intended for people and can conflict with the structured fields.
RFC 6591 adds the auth-failure feedback type for reports about a particular authentication method. Depending on the failure, the machine-readable part can contain fields such as:
Feedback-Type: auth-failureAuth-Failure: spf, signature, bodyhash, revoked, or another registered valueAuthentication-ResultsOriginal-Envelope-Id, Original-Mail-From, and Source-IPReported-DomainDKIM-Domain, DKIM-Identity, and DKIM-SelectorSPF-DNSDelivery-ResultThese fields describe what the reporting ADMD claims it observed. User-Agent is documentation only and is trivially forged. Source-IP, Reported-Domain, and the Authentication-Results field inside the report are not a replacement for checks performed by the reporting system or for authentication of the report message itself.
There are two related report families worth keeping separate:
Feedback-Type: abuse and reports a recipient complaint or other abuse signal.Feedback-Type: auth-failure and describes a failed SPF or DKIM check. Current DMARC failure reporting also uses ARF and adds the dmarc failure type and Identity-Alignment, as specified in RFC 9991.An ARF parser should accept only the report types it has a documented use for. Unknown feedback types and extension fields can be retained as uninterpreted evidence, but should not silently become business logic.
DMARC failure reports can contain message headers or a complete message and may expose personal or confidential data. DMARCPal does not process ruf reports, preserving privacy and keeping DMARC monitoring simple because this message-level channel is only sparsely useful in real-world deployments.
A robust deployment has more than one component. A useful shape is:
Internet SMTP
|
v
Dedicated report MX and mailbox
|
v
Raw-message quarantine and size gate
|
v
Source validation -> strict MIME parser -> normalized event queue
|
v
reviewed policy actionsThe public SMTP edge is untrusted. The mailbox or queue is a containment boundary, not a validation result. The parser is another boundary because MIME content, encoded data, and copied message headers are attacker-controlled input. Finally, the action worker needs its own authorization boundary so that a parser compromise cannot directly change DNS, delete campaigns, or alter every suppression list.
Keep raw mail and normalized events separate. The raw object is useful for a controlled investigation, while the normalized event should contain only the fields required for the next decision. Do not let downstream workers reparse arbitrary raw MIME each time they need one field.
There is no universal ARF trust mechanism. The ARF security considerations explicitly leave authentication and trust establishment to local policy. That means an allowlist based only on a claimed From: address is not a security control.
Use an out-of-band reporting relationship for each source that is allowed to trigger automation. Record the expected reporting domains, envelope addresses, DKIM signing domains and selectors where known, permitted report types, and the actions that source is allowed to influence. A source agreement can be narrow, for example, "this receiver may submit diagnostic events for this domain, but may not directly request subscriber deletion."
At the SMTP or message-ingest boundary, collect and evaluate:
Received chain, without treating message-supplied trace data as proofSPF and DKIM authenticate domain-level identities, not the truth of every ARF field. A passing DKIM signature on a report says that the signed report content was signed by that domain and was not altered after signing. It does not say the original message was abusive or that the reported authentication result was correct. Conversely, a report from a verifier whose own DKIM infrastructure is broken may fail to authenticate even when the report is legitimate. That is why authentication should produce a confidence and routing result, not a simplistic accept-or-trust flag.
S/MIME can provide stronger bilateral sender authentication when both parties can manage certificates and key rollover, but it is not a practical general Internet requirement. TLS is valuable for protecting a connection in transit; opportunistic SMTP TLS does not identify the report generator once the message is stored or forwarded.
Reject or quarantine reports when the source is unknown, the required source authentication fails, the source is not authorized for the destination domain, or the report type is outside the agreement. Do not make the parser more permissive to compensate for a failed trust decision.
The report mailbox is an inbound service. It should not be an ordinary shared inbox with a forwarding rule and a broad set of delegates.
Use a dedicated address and, where possible, a dedicated MX or inbound route. Disable automatic replies, forwarding, vacation messages, list expansion, and bounce generation for the report stream. An ARF report that triggers a reply can create a feedback loop, and an address that forwards to several destinations multiplies both privacy exposure and flood impact.
Protect access to the stored reports with a service identity and least privilege:
If a report is handed from the mailbox to an internal HTTP or queue endpoint, authenticate that hop separately with mTLS, a narrowly scoped signed token, or an equivalent mechanism. Authorize the specific sender and operation, not just possession of a network route. Network location and an internal IP address are not sufficient authorization.
ARF is deliberately extensible, and that flexibility is a parser attack surface. RFC 5965 says malformed ARF can be ignored or rejected, while its security section warns about extraordinarily large or intentionally malformed fields. Treat those recommendations as an engineering requirement.
Apply limits before full parsing:
Require the top-level content type and report type you support. Require the expected machine-readable part and validate its required fields and multiplicity according to the applicable RFC. Reject duplicate singleton fields, conflicting aliases such as historic and current field names, invalid dates, invalid IP literals, overlarge incident counts, and malformed addresses rather than guessing.
Do not render HTML, execute attachments, open URLs, resolve reported domains, or decode content into a browser-connected analysis process during ingestion. Treat a message/rfc822 part as an inert byte sequence until a separate, isolated analysis step needs it. Strip or escape control characters before putting field values into logs. Never interpolate untrusted values into shell commands, SQL, filesystem paths, email headers, or alert templates.
Preserve the original bytes and validation results for investigation, but pass a typed internal record to business logic. A useful normalized record might include the validated report source, report type, auth-failure method, reported domain, source IP, original envelope ID, original message ID if present, validation outcome, and a reference to restricted evidence. It should not carry arbitrary header names as executable attributes.
The same incident can produce retries, copies, and different report types. Message-ID is useful when present but is not guaranteed to be unique or honest. Original-Envelope-Id is also an assertion from the report generator. Use several fields when constructing an event key, for example:
hash(reporting-domain, report-type, auth-failure, reported-domain,
original-message-id, original-envelope-id, source-ip, time-bucket)Include a hash of the raw report for exact duplicate detection. Keep semantic deduplication separate from raw deduplication so a repeated report is not mistaken for a different event merely because a provider reformatted it. Choose the time bucket and fields based on the reporting source, and retain the original evidence when two reports collide.
Every downstream action should be safe to repeat. Applying a suppression should set a state with a reason and evidence reference, not append an unbounded duplicate row. Creating an incident should use a stable incident key. A report must never cause an irreversible action just because it is new to the queue.
Most importantly, do not let one unverified report:
Use ARF to prioritize investigation and to correlate with local sending logs. For high-impact actions, require a second signal, such as a matching local message ID, a known receiver agreement, an independent complaint event, or human approval.
There are two flood paths. A hostile actor can send forged reports directly to the mailbox, or can send messages that cause legitimate receivers to generate reports back to the victim. RFC 6591 calls out both automatic generation and distributed report floods. Current DMARC failure-reporting guidance also requires report generators to rate-limit outgoing reports and recommends aggregation with the Incidents field. A receiver cannot control what every reporter does, so the consumer still needs hard limits.
Set quotas at multiple levels:
Use a token bucket or equivalent bounded rate limiter, with a global circuit breaker. When a source exceeds its budget, keep a small representative sample and counters, then shed excess work. Do not let a single source consume the entire queue. Keep a separate emergency path for authenticated, contractually important sources only if that path has its own quota.
Aggregation and sampling are not the same. Aggregation can preserve an Incidents count and a representative set of fields. Sampling discards detail. Make that loss visible in metrics and alerts. Never interpret a rate-limited stream as evidence that the underlying failure rate is low.
The safest feedback loop is one that does not answer an ARF report. In particular:
From: or Original-Mail-FromReported-URI, Original-Rcpt-To, or message headersThe report itself may contain URLs, recipients, and sender addresses chosen by an attacker. Treat them as data. Never use them as destinations for a reply, webhook, callback, suppression confirmation, or escalation.
On the generation side, create reports only for an approved reporting relationship. Aggregate similar incidents, apply per-recipient quotas, and prefer a bounded diagnostic sample when a stream is exploding. RFC 9991 specifically recommends delaying and consolidating similar reports and rate-limiting outgoing reports to prevent denial of service.
Failure reports can contain full headers, recipient addresses, message bodies, DKIM canonicalized data, URLs, and forwarding destinations. They can expose information about legitimate messages that merely failed authentication. RFC 9991 recommends limiting the scope and duration of failure reporting, controlling destinations, applying redaction, and using secure channels.
Before enabling any automated flow, decide:
Encrypt raw reports at rest and in transit, keep them out of general support mailboxes, and separate retention of raw evidence from retention of aggregate counters. Hashing an address is not automatically anonymization if the input space is easy to guess, so use a keyed construction when a stable privacy-preserving correlation key is needed. Let legal and privacy requirements determine exact retention periods rather than copying a convenient number from another deployment.
An alert that says "ARF report received" is rarely useful. Monitor the safety properties of the pipeline:
Incidents valuesAlert on deviations from a source's baseline, a sudden new reporter, a source-authentication failure, quota exhaustion, and any action taken without the expected corroborating signal. Send alerts to a separately authenticated operations channel. Do not use an address copied from an incoming report as the alert destination.
Start with observation, not automatic enforcement:
The desired failure mode is boring: an untrusted or excessive report is retained as limited evidence, counted, and quarantined. It does not trigger an outbound loop, expose a mailbox, or make a high-impact change.
ARF automation is safe when the report is treated as hostile input carrying potentially useful, potentially false assertions. Authenticate and authorize the reporting source separately from parsing the format. Isolate the mailbox and parser, impose limits before decoding, deduplicate and rate-limit at several layers, minimize sensitive content, and require independent evidence before impactful actions.
That design turns authentication-failure reports into bounded security telemetry instead of a forged feedback loop or a report flood with administrative privileges.