> [Brian Candler]
> I think this goes back to my original point: aol.com should take
> responsibility for protecting their users against invalid
> bounces. That
> means using sender cookies (e.g. SRS) in *all* outgoing mail
> from aol.com,
> and rejecting bounces which are not signed.
I don't think that protects them from the exploit I've outlined. If
anyone gets a copy of a SRS-signed message, they can send a
legitimate-looking bounce regardless of the content. I'll let others
who know more about how hard this is to do decide how likely it is for a
spammer to obtain this information, but if they can, it is an open door.
I know that neither SPF or SRS will stop spam, but we certainly don't
want to open a validated channel for them to spam through.
Here are a couple of possible fixes for this exploit, some requiring
local storage, some not, giving various degrees of protection. The
first scheme retains Shevek's shortcut scheme for sending a bounce
directly back to the first hop). The rest of them break that
beautifully elegant scheme.
The schemes that break Shevek's shortcut method force a bounce to
traverse the same outgoing path the message took. While this is clearly
not optimal, I believe that legitimate bounces are a small part of
normal message traffic so this fact by itself should not impact
throughput much on real systems. Hopefully, someone more knowledgeable
about message traffic than myself can shed some light on that statement.
A) No SRS modification, minimal local storage
---------------------------------------------
This scheme allows a single spam to be delivered per SRS-signed address
harvested. Since I don't really know how hard it is to get someone's
SRS-signed envelope-sender information, I don't know if this is a
sufficiently high barrier for the spammers. The good part is that is
only requires local storage for each successful bounce message received
as opposed to all outgoing messages. I don't think it's possible for a
spoofed bounce message to beat a legitimate bounce message back to the
original forwarding MTA, but I'll leave that to the MTA experts to
answer. If that were possible, it would be serious as we need to
receive 100% of legitimate bounces.
1) When an MTA receives a bounce, validate the SRS0 hash.
2) If the hash verifies, check the local bounce cache for the
hash_value/timestamp. If it exists in the local cache, reject the
bounce.
3) If the hash_value/timestamp does not exist in the local cache, enter
it in the cache and accept the bounce.
B) Significant SRS modification, no local storage
-------------------------------------------------
This scheme includes the next hop address in the hash calculation. It
thereby causes rejection of a bounce coming from any other domain. The
cost of this particular scheme is twofold. First, it requires an
additional hash calculation at each forwarding hop. I'll let the MTA
experts pass judgment here, but avoiding open relaying via bounces is an
important goal and is worth some CPU cycles. The second cost is that
the envelope-sender address grows with each hop. While multiple
forwards could easily cause the address to exceed the 64-byte limit,
Shevek already states in his section 3.4 that the current SRS is likely
to exceed that limit anyway. Again, I'll let the MTA experts comment on
how much of a burden the longer address is. The entire message path in
the clear, but those are the only possible injection points for forged
bounce messages. This could be made stronger by reversibly encrypting
the next hop address at each stage, so it is not in the clear, using the
forwarding domain secret key salted with the previous link hash value.
I think that would be over-the-top, but quite secure.
1) Include the next hop domain in the SRS0 record hash calculation but
do not put it in the record. That is, calculate the hash over
<TT+next_hop_domain+original_hostname+original_username>. When a bounce
comes in, the MTA will put the connecting domain in the appropriate
place to do the hash validation. Each subsequent forwarder moves the
previous forwarder address from after the @ symbol to left of the
leftmost hash, calculates a hash over the address with the next hop
prepended, places this new hash at the leftmost end and appends it own
address after the @ symbol. This protects each subsequent forwarder's
address from later forgery. Here is an example showing the
envelope-sender (return-path) address as it passes through three
forwarders:
SRS0+HHH1+TT+original_hostname+original_username@forwarding_domain_1
SRS1+HHH2+forwarding_domain_1+HHH1+TT+original_hostname+original_usernam
e@forwarding_domain_2
SRS1+HHH3+forwarding_domain2+HHH2+forwarding_domain_1+HHH1+TT+original_h
ostname+original_username@forwarding_domain_3
2) If forwarding_domain_3 is unable to deliver the message to the next
hop, bounces it back to forwarding_domain_2 with the same return-path
minus the HHH3 and forwarding_domain_2 fields, as follows:
SRS1+HHH2+forwarding_domain_1+HHH1+TT+original_hostname+original_usernam
e@forwarding_domain_3
3) Upon receipt of the bounce, forwarding_domain_2 inserts the domain
name of the connecting machine (forwarding_domain_3) and verifies hash
HHH2 over:
forwarding_domain_3+forwarding_domain_1+HHH1+TT+original_hostname+origin
al_username
4) If the hash verifies, forwarding_domain_2 bounces the message back to
forwarding_domain_1 with the same return-path minus the HHH2 and
forwarding_domain_1 fields. Since it is now going back to the first hop
address, the return path looks like:
SRS0+HHH1+TT+original_hostname+original_username@forwarding_domain_1
5) Upon receipt of the bounce, forwarding_domain_1 inserts the domain
name of the connecting machine (forwarding_domain_2) and verifies hash
HHH1 over:
forwarding_domain_2+original_hostname+original_username
6) If the hash verifies, it accepts the bounce and sends it back to
original_username@original_hostname.
C) No SRS modification, lots of local storage
---------------------------------------------
This approach stores the forward-from and forward-to return-path
information for every message locally, not in the SRS address. To
defeat this approach, the spammer has to send the bogus bounce message
from one point on the original message outgoing path to the preceding
one. Since the spammer can't know the original message path, he is at a
disadvantage. Of course, he can guess that there were no forwarding
hops beyond the first one and he would be right most of the time. We
can defeat that by always using at least two forwarding hops instead of
one to hide the original forwarder, since Shevek's scheme only shows the
address of the last forwarder in the chain. This is not desirable, but
neither is open relaying. The real cost of this approach, however, is
that forwarding information must be kept on _every_ outgoing message,
since we can't know ahead of time which ones will come back. Though the
information can be discarded after a short while, storing it in the
first place may be burdensome.
1) For every outgoing SRS-signed message, store the SRS0 hash value,
timestamp, domain forwarded from and domain forwarded to.
2) When an MTA receives a bounce, if that MTA was the first hop,
validate the hash. If the hash validation fails, reject the bounce.
3) If the hash validates or the MTA was not the first hop, check the
outgoing message cache to see if that hash value/timestamp was forwarded
to the domain that is now attempting to deliver the bounce.
4) If the connecting domain attempting to deliver the bounce is the same
as the one the message was originally forwarded to, accept the bounce
and forward it back to the original domain (or local user) forwarded
from. Otherwise, reject the bounce.
--
Seth Goodman
-------
To unsubscribe, change your address, or temporarily deactivate your subscription,
please go to
http://v2.listbox.com/member/?listname=srs-discuss@v2.listbox.com