Last Comment Bug 373973 - (CVE-2007-1558) Security vulnerability in APOP authentication
: Security vulnerability in APOP authentication
[sg:moderate] public paper to be pres...
: fixed1.8.0.12, fixed1.8.1.4
Product: MailNews Core
Classification: Components
Component: Networking: POP (show other bugs)
: Trunk
: All All
-- normal (vote)
: ---
Assigned To: Christian Eyrich
: 378113 (view as bug list)
Depends on:
  Show dependency treegraph
Reported: 2007-03-14 14:03 PDT by Daniel Veditz [:dveditz]
Modified: 2009-01-22 10:17 PST (History)
10 users (show)
dveditz: blocking1.8.1.4+
dveditz: wanted1.8.1.x+
dveditz: blocking1.8.0.12+
dveditz: wanted1.8.0.x+
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---

proposed patch (8.21 KB, patch)
2007-03-16 13:47 PDT, Christian Eyrich
no flags Details | Diff | Splinter Review
updated patch (9.35 KB, patch)
2007-03-21 05:37 PDT, Christian Eyrich
no flags Details | Diff | Splinter Review
patch with simple validity-check (4.27 KB, patch)
2007-04-03 11:23 PDT, Christian Eyrich
no flags Details | Diff | Splinter Review
simple check 2 (4.11 KB, patch)
2007-04-17 03:26 PDT, Christian Eyrich
mozilla: review+
mozilla: superreview+
Details | Diff | Splinter Review
fix landed on trunk. (4.88 KB, patch)
2007-04-17 09:37 PDT, David :Bienvenu
dveditz: approval1.8.1.4+
dveditz: approval1.8.0.12+
Details | Diff | Splinter Review

Description User image Daniel Veditz [:dveditz] 2007-03-14 14:03:30 PDT
mail sent to
- - - - - - - - - - - - - - - - - -

I found a security vulnerability in the APOP authentication.  It is
related to recent collision attacks by Wang and al. against MD5.  The
basic idea is to craft a pair of message-ids that will collide in the
APOP hash if the password begins in a specified way.  So the attacker
would impersonate a POP server, and send these msg-id; the client will
return the hash, and the attacker can learn some password characters.

The msg-ids will be generated from a MD5 collision: if you have two
colliding messages for MD5 "<????@????>x" and "<¿¿¿¿@¿¿¿¿>x", and the
message are of length two blocks, then you will use "<????@????>" and
"<¿¿¿¿@¿¿¿¿>" as msg-ids.  When the client computes MD5(msg-id||passwd)
with these two, it will collide if the first password character if 'x',
no matter what is next (since we are at a block boundary, and the end of
the password will be the same in the two hashs).  Therefore you can
learn the password characters one by one (actually you can only recover
three of them, due to the way MD5 collisions are computed).

This attack is really a practical one: it needs about an hour of
computation and a few hundred authentications from the client, and can
recover three password characters.  I tested it against Thunderbird, and
it does work.

However, using the current techniques available to attack MD5, the
msg-ids sent by the server can easily be distinguished from genuine ones
as they will not respect the RFC specification.  In particular, they
will contain non-ASCII characters.  Therefore, as a security
countermeasure, I think Thunderbird (and other Mozilla derived mail
client) should reject msg-ids that does not conform to the RFC.

The details of the attack and the new results against MD5 needed to
build it will be presented in the Fast Software Encryption conference on
March 28.  I can send you some more details if needed.

Meanwhile, feel free to alert any one that you believe is concerned.
I am already sending this mail to the maintainers of Thunderbird,
Evolution, fetchmail, and mutt.  KMail already seems to do enough checks
on the msg-id to avoid the attack.

-- Gaëtan LEURENT
Comment 1 User image Christian Eyrich 2007-03-15 06:52:10 PDT
So if I understand that right in order to prevent the current attack, it would be sufficient to check if nsCRT::IsAscii(m_ApopTimestamp.get()) is true.
I'd nevertheless like to make sure the timestamp really conforms the RFC. I'm currently looking if a function for such a check already exists in the Mozilla code.
Comment 2 User image Daniel Veditz [:dveditz] 2007-03-16 11:27:14 PDT
Scott: blocking status on this one is your call.
Comment 3 User image Christian Eyrich 2007-03-16 13:47:16 PDT
Created attachment 258830 [details] [diff] [review]
proposed patch

I couldn't find an existing code in Mozilla so I wrote a routine to test for RFC compliance.
I don't really like the resulting code, but it works. Any other approach or critics to improve that routine is welcome.

Is a fairly good PCRE engine available in Mozilla (outside JS)?
Comment 4 User image David :Bienvenu 2007-03-16 14:02:19 PDT
Wow, thx, Christian. But there's a lot not to love about the resulting code - I'd strongly consider the nsCRT::IsAscii check first...

I don't know if there's a PCRE engine or anything similar in Mozilla, outside of js
Comment 5 User image Christian Eyrich 2007-03-16 14:15:39 PDT
> I'd strongly consider the nsCRT::IsAscii check first

You're right, that surely is a good idea.

For the rest - how to make the best of a bad job (what's the worst)? I'd like using string classed with iterators and something more robust. But I don't know how to look at the previous/next char with them.
Comment 6 User image Christian Eyrich 2007-03-16 16:03:44 PDT
Cleaned it up a bit and fixed two bugs but that doesn't make a beauty of it. So I'll wait for comments.
Comment 7 User image Daniel Veditz [:dveditz] 2007-03-19 10:29:12 PDT
Presuming this should block the next set of releases.
Comment 8 User image Christian Eyrich 2007-03-21 05:37:45 PDT
Created attachment 259195 [details] [diff] [review]
updated patch

Not nicer and even more tests. Previously I ignored that there might be more than one < or > respectively in the greeting.
E.g. this is a possible greeting
+OK my own POP3 > <fake@ü.org> server: <"x{"@[ne\ t]>, that was the msg-id<>.
but only <"x{"@[ne\ t]> is a valid msg-id. That means nothing outside the new routine can determine which part actually contains the timestamp - and so no IsAscii test can be performed before calling findCompliantMsgId() (and doesn't make sense afterwards).
Comment 9 User image Gaëtan LEURENT 2007-04-02 08:02:32 PDT
By the way, Mozilla does not offer a way for the user to ask for a strong authentication.  The user can only select "secure authentication" but the protocol is then autodetected when connecting to the server.  Therefore, is a user is using "secure authentication", the attacker would pretend to only support APOP, and will be able to recover the password, without any warning to the user.  It would be better to have a way for the user to say "I know that my server support CRAM-MD5, please use it or warn me".  Or maybe Mozilla could remember the authentication mode it used the last time and warn the user if it is no longer supported.
Comment 10 User image Christian Eyrich 2007-04-02 08:16:09 PDT
Yes, that's a wish expressed from time to time. On the other hand people argue that will make usage to complicated. It mainly is a question of UI, not implementation.
Comment 11 User image David :Bienvenu 2007-04-02 08:46:58 PDT
Christian, in the real world, it seems to me server greetings are not going to sprinkle things that look like msg-ids all over. Seems to me that scanning backwards from the end for a <> delimited msg-id is going to be fine, and checking the string inside that for ascii (and a '@') would be sufficient. Given that many clients weren't handling this correctly before, that argues that servers weren't generating multiple things in the greeting that looked like msg-ids, and counting on the client to pick out the one that was a legal msg-id.

So the algorithm might be:

1. Scan from the end of the greeting for a <> delimited msg-id, ascii and containing a '@', 

2. Loop until we find a legal msg-id or get to the beginning of the line.

'<' and '>' aren't legal characters in msg-ids, right, and they're not escaped, so this should be fairly simple. Or am I missing something?
Comment 12 User image Christian Eyrich 2007-04-03 04:34:42 PDT
David, you're right that it's very unlikely normal servers greetings are going to look like my example. My desire was to not only prevent current attacks by malicious servers but also set the highest hurdle possible for any future attacks.

< and > are legal on left as well on right side of a msg-id as long as those sides consist of a no-fold-quote or no-fold-literal, i.e. "xxx" resp. [xxx].
I don't know how common this is or if it's used at all.

Ignoring this, implementing the algorithm you proposed is fairly simple. I'd be even simpler if I knew how to do a search from right in Mozilla string objects.
Comment 13 User image David :Bienvenu 2007-04-03 06:41:41 PDT
Christian, look for RFind.
Comment 14 User image Christian Eyrich 2007-04-03 11:23:45 PDT
Created attachment 260484 [details] [diff] [review]
patch with simple validity-check

Thanks David.
That patch should do the trick. With this procedure > always terminates a msg-id but < can occur within it (e.g. <xx<x@xx>). That's not valid but the test is cheap.

I only hope I didn't make the ascii-check stuff more complicated than necessary.
Comment 15 User image David :Bienvenu 2007-04-16 12:29:38 PDT
Comment on attachment 260484 [details] [diff] [review]
patch with simple validity-check

Christian, thx for doing this! - it looks OK. Is there any reason not to put this code in nsPop3Protocol.cpp? Is any other code likely to care about APOP?
Comment 16 User image Christian Eyrich 2007-04-16 13:29:23 PDT
Uhm yes you're right. I just had put it there without much thinking. It'd be better in nsPop3Protocol.cpp.
I can do this tomorrow.
Comment 17 User image David :Bienvenu 2007-04-16 13:31:19 PDT
Comment 18 User image Christian Eyrich 2007-04-17 03:26:54 PDT
Created attachment 261783 [details] [diff] [review]
simple check 2

Moved getApopTimestamp into nsPop3Protocol and simplified it a bit more by using the member variables directly.
Comment 19 User image David :Bienvenu 2007-04-17 08:58:39 PDT
Comment on attachment 261783 [details] [diff] [review]
simple check 2

looks good, thx, Christian. I'll probably change it to GetApop instead of getApop and change the while (1) to while (PR_TRUE) before landing...
Comment 20 User image David :Bienvenu 2007-04-17 09:37:46 PDT
Created attachment 261808 [details] [diff] [review]
fix landed on trunk.

this is what I landed on the trunk - I just made the changes I described earlier...
Comment 21 User image David :Bienvenu 2007-04-17 09:38:29 PDT
Comment on attachment 261808 [details] [diff] [review]
fix landed on trunk.

requesting approval for 1.8.1 branch.
Comment 22 User image David :Bienvenu 2007-04-17 09:38:52 PDT
fixed on trunk
Comment 23 User image Daniel Veditz [:dveditz] 2007-04-18 16:26:47 PDT
Wouldn't we want this on the 1.8.0 branch for Thunderbird 1.5.0.something too?

I'll let mscott deal with the 1.8.1 approval for this. Not sure we're shipping a tbird based on, might wait until
Comment 24 User image David :Bienvenu 2007-04-18 17:03:32 PDT
Comment on attachment 261808 [details] [diff] [review]
fix landed on trunk.

yes, you're right - we'd want this for the next 1.5 release...
Comment 25 User image Daniel Veditz [:dveditz] 2007-04-19 10:29:53 PDT
Comment on attachment 261808 [details] [diff] [review]
fix landed on trunk.

approved for and, a=dveditz for release-drivers
Comment 26 User image David :Bienvenu 2007-04-23 09:30:22 PDT
fixed on 1.8.0 and 1.8.1 branches
Comment 27 User image Daniel Veditz [:dveditz] 2007-05-09 13:47:58 PDT
For future reference:

Gaëtan presented at FSE March 28 (as he said)

And posted to BUGTRAQ about it April 2

Both of the above link to slides of his talk.

Another group presented something very similar as a Rump talk at the same conference, which got filed as bug 378113.

In the second set of slides they claim to have extended the attack to 31 password characters
Comment 28 User image Daniel Veditz [:dveditz] 2007-05-09 13:49:57 PDT
*** Bug 378113 has been marked as a duplicate of this bug. ***
Comment 29 User image Daniel Veditz [:dveditz] 2007-05-09 13:52:49 PDT
raising severity to "sg:moderate" based on the longer password claim (comment 27)
Comment 30 User image Carsten Book [:Tomcat] 2007-05-16 01:27:59 PDT
Christian, Gaëtan, are there any steps to reproduce or a testcase for this bug that i can run to verify fixed this bug ?

Note You need to log in before you can comment on or make changes to this bug.