Prevent same-list replays
over on #158 (closed), we discussed cross-list replay attacks, which are resolved by requiring
x-listname: doesn't mitigate same-list replay attacks for control messages.
There are several possible mitigations, most of them having to do with some sort of stored state anti-replay protections, which may or may not introduce more problems than they solve ;)
Here are three suggestions, along with some caveats:
- for each admin for a given list, keep track of the OpenPGP timestamp of the signature of the last-received message from that admin as
- when a new message comes in for that list from that admin, verify that the signature is later than the associated
This has a few potential traps lurking in it:
- what if the admin is on a machine with a shifting clock? can they lock out their future messages if they accidentally send one message from the year 3000?
- what if messages get delayed and re-ordered in transit?
- for each admin for a given list, keep track of all signatures ever seen by that admin as a list
known_signatures(you can get a
SIG_IDfrom the GnuPG status lines which should be globally unique)
- when a new signed, verified message comes in from that admin for that list, compare the signature with the
known_signatures. If it's already been seen, reject the message.
- this appears to grow without bound, which is problematic in (at least) two ways:
- a malicious list admin could stuff the server full of records to cause it to overflow
- it creates a log of who interacts with the server and when, which is a chunk of metadata that the list operators might not want to be liable for.
We can synthesize the two above with a bit more complexity, and with some baseline assumptions/requirements about system clocks. Pick two time allowances,
F ("forward skew") and
B ("backward skew"). (consider
F=B=1 week for now)
- When a message comes in at server time
Tfor a given admin on a given list, and that message signature has time
S, reject the message if
S < T-Bor
S > T+F
- if the message is not rejected due to time, compare it's signature ID with
known_signaturesfor that admin for that list.
- if it is already present, reject the message
- if it is not present, store
known_signaturesand process the message
- during regular maintenance at server time
X(cronjob? scheduled timer?), delete all entries in
S < X-B
- this is more complex to implement than the other proposals, and has more types of errors/message rejections
- you have to choose
B-- more knobs to twiddle, yuck. Probably
Bshould be greater than the maximum expected SMTP delay time (4 days), but not too much longer (to minimize data retention).
Fneeds to be set to accomodate clock skew seen in the wild, which i don't have data on.
- what happens if the clock on the server itself is wacky? Does schleuder need to depend on having a mostly-correct system clock?