Thandy attacks / suggestions

Justin Samuel jsamuel at
Mon Dec 15 18:41:48 UTC 2008

Roger Dingledine wrote:

> 1) Apparently python's urllib doesn't check SSL certs or cert chains.
> So while we may think that handing it
> will mean it'll complain if the cert is wrong, apparently we'd be
> mistaken. His suggested fix was to ship our SSL cert with the updater;
> that's no fun if we change our cert or if we add a mirror with a cert,
> though. He didn't have a second suggested fix. At least we know now.  

This might have been a mix of conversations. In any event, coderman
mentioned M2Crypto in his reply and that is the solution many people do
use for ssl cert checking with urllib in python. Possibly coderman
thought M2Crypto was more dated than it is because the first result in
google is, unfortunately, still the old author's homepage. Here is the
current M2Crypto:

For what it's worth, ssl usage will get better with python 2.6:

It appears, though, that even with the new ssl module in python 2.6,
M2Crypto will still be the more secure way to do things (ability to
disable SSLv2, require stronger ciphers).

> 7) We had a long discussion about the "what if the attacker gets a copy
> of the timestamp key" worry. This issue seems to be the big remaining
> question in the design: an attacker who can generate his own timestamp
> file and either modify the repository or intercept client requests can
> freeze clients in time, so they never know about updates and never realize
> they're frozen. Since the timestamp file is only signed by the timestamp
> key, he can also mix-and-match which hashes he puts in the timestamp file:
> a keylist from time A, a mirror list from time B, a bundle from time
> C. Some of these attacks are mitigated by having clients never replace
> their current files with older files. But a newly bootstrapping client
> can still be tricked into installing a package that's 18 months obsolete.

For the case where an attacker has the timestamp key, there are two
primary goals. First is that the attacker should not be able to do
anything other than keep the client on the the client's current version
of any files. Second is that the client needs a way to realize at some
point that something is wrong and there may be updates they are not
discovering. In the case of a newly bootstrapping client, this can be
read as the client not accepting initial files that are outdated.

Completely preventing an attacker in control of the timestamp key from
affecting which files the client uses doesn't seem likely. However, what
can be done is to only allow an attacker to provide a snapshot of the
real repository at some point in time (not allowing mix-and-match, as
described by Roger above). --- With proper expiration times on other
files, this snapshot has to be a very recent one.

One option that Justin Cappos and I mentioned to Roger which he asked us
to elaborate on here is that of adding another level of metadata
indirection between the timestamp file and the files referenced in the
timestamp file. The current arrangement of having the hashes/timestamps
of multiple files listed directly in the timestamp file means that the
timestamp key is actually responsible for more than indicating if the
repository contents have changed. Instead, the timestamp key is also
responsible for telling the client more specifically what is available
on the repository.

This ability for an attacker with the timestamp key to mix-and-match
what the client sees can be eliminated by not having the timestamp file
directly list fine-grained details of the repository state. Instead, a
new file whose sole purpose is to provide that information could be the
only file whose hash and timestamp are listed in the timestamp file.

If you think of the current system like this:

timestamp file -> [hash/ts/size of bundleinfos, keys.txt, mirrors.txt]

then adding this extra level of indication would look like this:

timestamp file -> [hash/ts/size of main metadata file]
main metadata file -> [hash/ts/size of bundleinfos, keys.txt, mirrors.txt]

This leaves the more important issue of how the client will know if the
metadata they are getting from the repository is stale, even if the
timestamp file's signature is fresh (i.e. a possible attack by an
attacker who has the timestamp signing key). This comes back to the
importance of making sure all other files besides the timestamp file
have their timestamp and expiration time checked.

Adding the extra level of indirection makes this a bit easier and
increases the expiration time that is safe to use in bundleinfo files
and others. This is because a single file (the "main metadata file"
above) whose signing key is more secure than the timestamp key can have
a shorter expiration time (not as short as the timestamp file's, of
course) and be regularly resigned with more ease than the other files.

This would mean an extra role/key is added to the design. In that sense,
it's similar to "A2" described by Roger, but the form of indirection is
different. It would also make the timestamp file a little smaller.

> C) We should stop letting every mirror serve the timestamp file, but
> instead serve it from a smaller more trusted subset of the mirrors
> (maybe all the ones with the "official" flag set). It's tiny anyway,
> so the only issue this introduces is less robustness in the face of an
> attacker who knocks down mirrors.

Serving the timestamp file from trusted mirrors is a good place to use
SSL with proper certificate checking. It can stop freeze attacks by a
MITM within the expiration time of the timestamp file (which is 6 hours
according to the spec).

Justin Samuel

More information about the tor-dev mailing list