You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Security
Fixed a path traversal in the failure report sample filenames written by --output (GHSA-c284-w5m6-jhjm, affects 9.0.6 through 11.0.0). save_output() named each failure report's message sample after the sample's Subject header, falling back to the raw, unsanitized subject whenever sanitizing it produced an empty string. A subject consisting only of path separators and dots — ../../../ or / — sanitizes to nothing, so the raw value reached os.path.join() and the .eml file was written outside the samples directory, or at an absolute path. The subject comes from a message that failed authentication, so anyone who can send mail to a monitored mailbox controls it. The filename is now sanitized at write time and falls back to sample, and the filename_safe_subject key that a library caller may supply alongside the subject is no longer trusted.
Fixed unbounded decompression of report attachments (GHSA-43qf-f35w-2x4r, affects all versions through 11.0.0). extract_report() inflated gzip and zip attachments with no limit on the output size. The attachment's content is chosen by whoever sent it, and deflate reaches compression ratios of about 1000:1 on degenerate input, so a 100 KB attachment from any sender a monitored mailbox accepts inflated to 100 MB, with a peak of about twice that. Extraction now stops at 100 MiB of decompressed data and raises ParserError. The limit is deliberately not configurable: real DMARC aggregate, failure, and SMTP TLS reports are orders of magnitude smaller.
Bug fixes
CSV output (failure.csv, and the other CSV renderers) no longer raises _csv.Error on Python 3.10 when a report field contains a NUL character. Python 3.10's csv writer rejects any field containing NUL unless an escapechar is set (CPython issue 97503, a 3.10 regression fixed in 3.11+). Failure report text fields (subject, user agent, authentication results, addresses, and more) come from untrusted mail, so a NUL byte anywhere in one made parsed_failure_reports_to_csv() — and therefore save_output() — raise on 3.10, uncaught by the CLI's except (OSError, ValueError) around save_output. The character is now stripped from CSV fields on every Python version, matching the sanitizing already applied to sample filenames.