foxcpp / foxcpp/maddy

SPF reported as failing due to allowing all when it is disallowed

Open
#530 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Go
Stars
6.1k
Forks
327
PR merge metrics
No merged PRs in 30d

Description

# Describe the bug

Maddy is reporting a `MAIL FROM` address as having SPF insecurely set (allowing "all"?) when it does not.

Note that other emails get through just fine (ex. GMail, ProtonMail).

# Steps to reproduce

The incoming mail path looks like this:

```mermaid
graph LR;
SES-->Haraka;
Haraka-->Maddy;
```

I'm trying to send an email from `sender.tld` to `recipient.tld`, with `sender.tld` being the MAIL FROM address on SES.

The email gets all th way to maddy, but maddy fails the SPF due to "matched all" (see logs). I assume this means that the SPF policy was determined to match `all`, but when I check my DNS I'm 100% sure it doesn't and never has. The record is:

`v=spf1 include:amazonses.com -all`

I've used the google toolbox to check the record so it's not just me either. In fact I'm fairly sure this rule is inserted by AWS SES automatically when you create a MAIL FROM alias because I don't see it in my infra code (and if I try to manually add one it collides)...

## (Insecure) Workaround

(Don't try this at home folks!)

So of course, to test my hypothesis I've set `fail_action ignore` under `spf` in the local routing `check` stanza and the email gets through.

# Log files

```
2022-08-31T13:22:22.061Z smtp: incoming message {"msg_id":"b7f1f921","sender":"01010182f4112163-3cf399e1-2b65-476b-9647-256c9dce24d3-000000@bounce.sender.tld","src_host":"haraka-bfzsx","src_ip":"10.244.206.187:58284"}
2022-08-31T13:22:22.075Z smtp: RCPT ok {"msg_id":"b7f1f921","rcpt":"admin@recipient.tld"}
2022-08-31T13:22:22.206Z smtp/pipeline: quarantined {"check":"check.spf","msg_id":"b7f1f921","reason":"matched all","smtp_code":550,"smtp_enchcode":"5.7.23","smtp_msg":"SPF authentication failed"}
2022-08-31T13:22:22.243Z smtp: accepted {"msg_id":"b7f1f921"}
```

After doing the workaround:

```
2022-08-31T13:37:25.426Z smtp: incoming message {"msg_id":"df3f0b88","sender":"01010182f41ee88d-051c24d3-69a1-43f9-95f4-f9f7b994610b-000000@bounce.sender.tld","src_host":"haraka-6wxhv","src_ip":"10.244.192.190:50182"}
2022-08-31T13:37:25.448Z smtp: RCPT ok {"msg_id":"df3f0b88","rcpt":"admin@recipient.tld"}
2022-08-31T13:37:25.517Z smtp/pipeline: no check action {"check":"check.spf","msg_id":"df3f0b88","reason":"matched all","smtp_code":550,"smtp_enchcode":"5.7.23","smtp_msg":"SPF authentication failed"}
2022-08-31T13:37:25.631Z smtp: accepted {"msg_id":"df3f0b88"}
```

# Configuration file

```
$(hostname) = mail.recipient.tld
$(primary_domain) = recipient.tld
$(local_domains) = $(primary_domain)

state_dir /data
log stderr_ts

tls file /data/tls/tls.crt /data/tls/tls.key {
protocols tls1.2 tls1.3
}

auth.pass_table local_authdb {
table sql_table {
driver sqlite3
dsn credentials.db
table_name password
}
}

storage.imapsql local_mailboxes {
driver sqlite3
dsn imapsql.db
}

# SMTP
hostname $(hostname)

msgpipeline local_routing {
destination postmaster $(local_domains) {
modify {
# Allow + aliases
replace_rcpt regexp "(.+)\+(.+)@(.+)" "$1@$3"
# Allow . aliases
replace_rcpt regexp "(.+)\.(.+)@(.+)" "$1@$3"
replace_rcpt file /etc/maddy/aliases
}

deliver_to &local_mailboxes
}

default_destination {
reject 550 5.1.1 "No such user"
}
}

smtp tcp://0.0.0.0:2525 {
limits {
all rate 100 1s
}

check {
dnsbl
require_mx_record
dkim
spf {
softfail_action ignore
}
}

source $(local_domains) {
reject 501 5.1.8 "use submission for outgoing SMTP"
}

default_source {
destination postmaster $(local_domains) {
deliver_to &local_routing
}

default_destination {
reject 550 5.1.1 "No such user"
}
}
}

submission tcp://0.0.0.0:587 tls://0.0.0.0:465 {
limits {
all rate 50 1s
}

auth &local_authdb

source $(local_domains) {
destination postmaster $(local_domains) {
deliver_to &local_routing
}

default_destination {
modify {
dkim $(primary_domain) $(local_domains) mail
}

deliver_to &remote_queue
}
}

default_source {
reject 501 5.1.8 "Non-local sender domain"
}
}

# Remote delivery
target.remote outbound_delivery {
limits {
destination rate 20 1s
destination concurrency 10
}

mx_auth {
dane
mtasts {
cache fs
fs_dir mtasts_cache/
}
local_policy {
min_tls_level encrypted
min_mx_level none
}
}
}

target.queue remote_queue {
target &outbound_delivery

autogenerated_msg_domain $(primary_domain)
bounce {
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
reject 550 5.0.0 "Refusing to send DSNs to non-local addreses"
}
}
}

# IMAP
imap tcp://0.0.0.0:143 tls://0.0.0.0:993 {
auth &local_authdb
storage &local_mailboxes
}

openmetrics tcp:0.0.0.0:9749 { }
```

# Environment information

* maddy version: 0.6.2

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.