Closed ell1e closed 1 week ago
The expected result you describe it pretty much the opposite form the current intentional behavior, which picks the most "valid" one to show. I'm also unaware that the RFC describes such a behavior as you want.
If you want to have more control over which Authentication-Results header (ARH) is used take a look at https://github.com/lieser/dkim_verifier/wiki/Account-Options#trusted-authentication-servers.
Of course if all ARHs contain a fail result, the add-on should not make a valid result out of it. Could you send me one affected e-mail as a saved eml file to lieser+dkim@posteo.net (or at lest the complete headers)? Would make it a lot easier to figure out what is going wrong. If you don't have an email you would be willing to share with me we could also try to see if the debug logs are enough.
What I proposed is the most defensive default behavior I could possibly think of, in case no specific server is marked as trusted. I think that would make the most sense if no server is marked as trusted to fail on whatever fail/none is found anywhere in the chain, since then an attacker could at best only mark themselves as failed (which seems like a bonus if they do, if anything).
I did some more testing, and for my work e-mail a few hours ago I made the change of making my SMTP strip any external "Authentication-Results" headers which works splendidly as a fix for this. It prevents the addon from picking up any untrusted external headers. However, for my private e-mail I don't have that sort of access to the SMTP server, so it would be nice if in such a situation the default behavior was safer.
Thanks for providing me the e-mail. Like you noticed yourself already it contained a third ARH that did not show up in your screenshot, where the add-on did pick up the valid result from.
I totally agree that the current default behavior could be considered insecure. If one is concerned about such attacks the already mentioned trusted authentication servers needs to be configured for each account! As the RFC requires the servers to strip any ARH result with it's own server-id, this should ensure you see only ARH from your server.
I choose this default because I fear for many it is to complicate if they need to configure this id. My admittedly a little weak justification for this suboptimal default behavior (from a security perspective) is that that I'm not aware of ARH spoofing being widely used as an attack.
I will think more about your proposal, like you may have noticed I'm currently not yet that convinced of it. In some cases (especially for SPF, but also DKIM with e.g. mailing lists) and under the assumption the ARH header is not spoofed, I could imagine cases there one would like to see the more valid result of an earlier ARH (this of course would be best combined with ARC #87). And your proposal would not prevent attacks in all cases, at least as long ARH reading can be enabled globally. Currently you could have two accounts, account A adding ARH, but the other account B not. If now one does not take the effort to enable ARH reading just for A, ARH spoofing would still be possible with your proposal for B.
One better default behavior I have been thinking about is trying to guess some reasonable default for the allowed server id from the configured server domain or e-mail address of the account. But I imagine this maybe to often resulting in a server id that does not match the correct one.
And your proposal would not prevent attacks in all cases, [...]
While that is true, it might be pretty safe when ignoring any Authentication-Results
that contains any DKIM info other than dkim=none
if there isn't actually a DKIM signature. Then you'd cover the common case where at minimum one trusted intermediate SMTP checks DKIM but only inserts headers when there was DKIM present.
it is to complicate if they need to configure this id.
It may not need to be, since I think the only "attack" might be an intermediate intentionally(!) trying to make DKIM incorrectly fail, which seems unproblematic. And just guessing a server id seems less safe than failing on any dkim=fail or dkim=none found. My apologies if I'm missing something, however.
For what it's worth, I just confirmed from digging in my mails that one of my accounts uses multiple subdomains to add in the Authentication-Results header. Therefore, unless it is configured to strip out all other subdomains which I assume it may not be, it's not possible to set a guaranteed safe set of server ids. However, failing on any dkim=fail
or dkim=none
should be safe for my config if I'm not mistaken, since all my accounts have a trusted SMTP at the top of the chain that will add the failure whenever applicable.
The problem I see with setting multiple hosts A, B is that perhaps an attacker could simply add a fake Authentication-Results header with host B, and the provider host A would perhaps only filter out host A, wouldn't it? So it seems to me like multiple hosts is inherently prone to tampering, while simply failing on any fail
isn't. I might be misunderstanding this, however.
I think I now understand what your concern is with setting up a secure manual configuration.
user@example.com
example.com
example.com
used multiple Mail Transfer Agents (MTAs) that add ARHs with different authserv-id
: authserv_1.example.com
, authserv_2.example.com
. Now if you would configure as trusted authserv-id
both authserv_1.example.com
and authserv_2.example.com
, you are worried if your provider example.com
will always remove ARHs from both authserv-id
it uses regardless through which MTA it was processed.
The I think relevant parts from the RFC are https://www.rfc-editor.org/rfc/rfc7001#section-1.2, https://www.rfc-editor.org/rfc/rfc7001#section-1.6, https://www.rfc-editor.org/rfc/rfc7001#section-2.4 and https://www.rfc-editor.org/rfc/rfc7001#section-5.
The RFC does not explicitly state what must happen.
But I think the intend is clear: all MTAs from the example.com
provider should be in one Administrative Management Domain (ADMD), in this case example.com
. When receiving a message from outside containing an ARH, all ARHs with an authserv-id
ending with the example.com
domain should be removed, meaning where is no security issue of trusting both hosts.
Anything else I would consider bad practice by the mail provider.
Now if you are talking about wanting to trust multiple authserv-id
from different ADMDs:
Unless you can guarantee that messages will always pass through both ADMDs, and no untrusted MTA comes after the message goes through a ADMD:
Yes you are correct, a targeted attack would be probably possible.
But I fail to see how your proposal would help in this case.
Now don't get me wrong, your proposal works as a potential better default to the current one of simply trusting all ARHs.
All the above is about if your proposal could also improve the security over the already possible manual configuration. Currently I fail to see this, at least under the assumption that the trusted hosts follow the intend of the RFC.
Now don't get me wrong, your proposal works as a potential better default to the current one of simply trusting all ARHs.
Yes I agree. While I have some thoughts on the multiple hosts of same provider situation, I don't think it's super relevant due to this point. Users who don't trust their provider to filter out things properly for such a multi domain situation can then just stick with the fail on any failed header default.
Edit: for what it's worth, my thoughts are if the RFC doesn't explicitly state this multi host handling, I don't trust the providers to do it. OpenDKIM for example doesn't have the greatest defaults either if you ask me, and this seems like a slightly arcane problem to be aware of. So I'm pessimistic about providers being aware.
One better default behavior I have been thinking about is trying to guess some reasonable default for the allowed server id from the configured server domain or e-mail address of the account. But I imagine this maybe to often resulting in a server id that does not match the correct one.
I decided that this initial approach I wanted to do initially will probably fail to often, e.g. when a provider supports multiple top domains.
I have been thinking about your proposal for choosing to show the worst result. In most cases this will probably do what we want, but I see a problem for e-mails that are not signed at all.
If the sender already adds an ARH claiming a dkim=pass
, but the receiving server does not add a dkim=none
result, we would still show the wrong DKIM result.
My provider seems to behave that way, and your comment https://bugzilla.mozilla.org/show_bug.cgi?id=265226#c98 indicates yor provider does too.
What I currently plan to implement, unless you can come up with a plausible scenario where this would fail:
authserv-id
for an account, trust all ARHs that match this.
authserv-id
*
, trust all ARHs.
authserv-id
is configured, use the following as the new default behavior:
authserv-id
from the first ARH.
authserv-id
in this step, even for an e-mail not signed by DKIM.authserv-id
from the first ARH.
authserv-id
.The most likely attack still possible that I see with the above is if the user has a (second) account configured that does not write any ARH at all. Unless ARH reading is disabled on this account, an attacker can still show any ARH result he wants. But unless we want to change that ARH reading can no longer be globally enabled but just for each account, I don't see how we could improve this.
I think your plan will work perfectly in case the incoming server adds an ARH. In cases where it doesn't, it's hard to keep the user safe anyway.
My provider seems to behave that way, and your comment https://bugzilla.mozilla.org/show_bug.cgi?id=265226#c98 indicates yor provider does too.
I have a theory why that is. OpenDKIM's default behavior seems to be to not write ARH when there's no DKIM present, rather than adding dkim=none
, see AlwaysAddARHeader
which defaults to off. I assume a lot of provider use OpenDKIM with default settings. Perhaps it would be useful to request from OpenDKIM to change the default, although who knows what cursed protocol corner cases may prevent them from doing so.
Changed the default behavior. Decided to not implement the trust all mode, if someone needs this we can always re-add it later.
I will keep the issue open until the documentation is adapted.
Documentation is updated.
Thank you so much! This is a very exciting update.
Setup for the bug: Because I use automatic PGP on unencrypted incoming mail provided by the paid e-mail provider I use, I have to disable DKIM checking through the addon itself because the automatic encryption breaks the signature. I therefore have to rely on DKIM Verifier displaying the results of the "Authentication-Results" headers for me. My usual developer e-mail is forwarded through a custom SMTP that I run that adds DKIM check results, and then ends up at an SMTP by a standard paid e-mail provider that also adds DKIM check results before applying Auto-PGP. You can see both of these
Authentication-Results
headers in the chain below, the lower one being from my forwarder SMTP.Expected result: As soon as DKIM Verifier finds any Authentication-Results headers somewhere in the entire chain that say "dkim=fail" or "dkim=none", even if that may also trigger on a spoofed fail result attached by the sender to the return path, that should lead to a fail being displayed.
Actual result: As soon as the top-most Authentication-Results header is present and mentions DKIM, DKIM Verifier seems to display "Valid", even if that very top-most header says "fail". This is with local DKIM check disabled, due to above reasoning.