Default missing Feedback-Type and Authentication-Results in failure reports (#332) (#831)

Some Exim/cPanel-based gateways send DMARC failure reports without a
machine-readable message/feedback-report part. parse_report_email()'s
plain-text fallback synthesizes a minimal feedback report with only
Arrival-Date and Source-IP, but the Elasticsearch/OpenSearch outputs
access feedback_type and authentication_results with hard key lookups,
so every such report was archived but never indexed, failing with
"Failure report missing required field: 'feedback_type'".

parse_failure_report() now defaults feedback_type to auth-failure
(RFC 5965 3.1) and authentication_results to None (RFC 6591 3.1) with
logged warnings, matching the existing handling of the REQUIRED
Auth-Failure and Identity-Alignment fields. Adds a sanitized sample
and a regression test asserting the sink-required keys are present.
This commit is contained in:
supaeasy
2026-07-20 15:21:55 -04:00
committed by GitHub
parent 5dc83613e6
commit d9f6532841
4 changed files with 99 additions and 0 deletions
+12
View File
@@ -191,6 +191,18 @@ class Test(unittest.TestCase):
)
print("Passed!")
def testFailureSampleWithoutFeedbackReportPart(self):
"""A plain-text-only failure report (no message/feedback-report part)
must still contain every field the Elasticsearch/OpenSearch outputs
access with hard key lookups (issue #332)"""
sample_path = "samples/failure/exim_plain_text_only_no_arf_part.eml"
result = parsedmarc.parse_report_file(sample_path, offline=OFFLINE_MODE)
assert result["report_type"] == "failure"
report = cast(FailureReport, result["report"])
assert report["feedback_type"] == "auth-failure"
assert "authentication_results" in report
assert report["source"]["ip_address"] == "203.0.113.68"
def testFailureReportBackwardCompat(self):
"""Test that old forensic function aliases still work"""
self.assertIs(