GnuPG signed message spoofing vulnerability
An advisory about a problem in GNU Privacy Guard (GnuPG) would normally cause worries about an implementation flaw leading to insecurely encrypted data. Thankfully, this particular vulnerability does not fall into that category and data encrypted using GnuPG is not at risk from it; it is, instead, a hole which allows attackers to spoof signatures. This vulnerability highlights an interesting interaction between GnuPG and the applications that use it. The flaw is not so much in how GnuPG does its work, rather it is in how it presents it.
GnuPG is an implementation of the OpenPGP standard which governs messages encrypted with public-key encryption. The standard is described in RFC 2440 and is descended from the original Pretty Good Privacy (PGP) program that Phil Zimmerman released (much to the chagrin of the US Government) in 1991. Many different mail programs use GnuPG (or the related GnuPG Made Easy (GPGME) library) to handle encrypted email; these programs include most open source email clients (KMail, Evolution, Thunderbird via the EnigMail plugin, mutt, etc.). All are vulnerable to the spoof - as is the gpg command-line tool, depending on how it is used.
One of the features of OpenPGP is digital signing of messages so that the recipient can ensure that the message they receive is the same as the one that was sent. It is this digital signature that is vulnerable to this attack as it can be spoofed; making it appear that unsigned text is covered by a valid signature. An attacker can insert malicious text into an existing message and have it appear to have been sent by the signer.
OpenPGP messages consist of a set of "packets" that correspond to different sections of a message (plaintext, encrypted, signature, compressed, ascii-armored, etc). Taking two valid OpenPGP messages and concatenating them produces a longer, but still valid, OpenPGP message. The simplest way to exploit the flaw is to take a plaintext packet and add it to the front of a signed plaintext packet. If the user attempts to verify the message by invoking gpg < msgfile, they will see the contents of both of the plaintext packets followed by a statement that the signature was verified. Nothing in the output indicates the presence of two packets with different signature status.
If this were the only issue, there would be a relatively easy, but not completely satisfying, workaround; do not redirect stdin from a file when using gpg. When it is invoked as gpg msgfile, GnuPG writes each individual plaintext packet into a separate file and, depending on the filenames specified in the packet, the above example would either create two files or prompt asking whether to overwrite when it encounters the second packet. That prompt, or the presence of two files, might be enough to alert the observant user to an anomaly, but is hardly foolproof. Unfortunately, mail clients typically invoke gpg via the output end of a pipe which allows them to be spoofed.
GnuPG does provide the --status-fd mode to prevent just this kind of attack by producing more status information on the specified file descriptor. The status information is not particularly user-friendly and might not alert a casual user to the spoof, but it certainly can be used by a program to detect the spoof. This is how GnuPG recommends that it be used by other programs but the developers of many mail clients ignored that advice with the result that their code is vulnerable. Normally this might be considered a problem for the mail client developers to solve, but the GnuPG team decided to make changes to GnuPG and GPGME to alleviate the problem.
Updated versions of GnuPG will no longer process multiple messages in a single invocation, avoiding the mingling of packets with different signature status. GPGME has been changed to avoid the spoofing even when it is using a vulnerable version of GnuPG. It is likely that the various mail clients will need to be updated eventually as well because they may well rely on GnuPG to process multiple messages in a single pass. The mail clients may not correctly process all of the email types that they did in the past, but they will not be vulnerable to this kind of attack.
The advisory has a wealth of information about the flaw and various ways that it can be exploited; it is well worth a read for those interested. This is an interesting bug because it lives between the GnuPG software and its users (both human and program). The GnuPG developers could have pushed this off as a problem for those users, but took a more helpful approach. If the command-line version (gpg < msgfile) of the flaw did not exist, it seems possible that they would have chosen differently and the mail client development teams would instead be scrambling to release updates.
Index entries for this article | |
---|---|
GuestArticles | Edge, Jake |
Posted Mar 8, 2007 6:50 UTC (Thu)
by dd9jn (✭ supporter ✭, #4459)
[Link]
Posted Mar 8, 2007 9:57 UTC (Thu)
by evgeny (subscriber, #774)
[Link] (8 responses)
Posted Mar 8, 2007 10:01 UTC (Thu)
by evgeny (subscriber, #774)
[Link] (7 responses)
> 4.16) Can't we have a gpg library?
?!
Posted Mar 8, 2007 18:32 UTC (Thu)
by kingdon (guest, #4526)
[Link] (6 responses)
Well, the FAQ doesn't elaborate, but it is generally good security practice to try to isolate different components, so that bugs or compromises in one would not tend to affect the others. For example, the way postfix is broken into several executables, or the way it is widely considered to be bad to have a GUI application setuid. Now, in the GPG context it isn't quite as clear-cut, since GPG isn't setuid, but still, the number of possible couplings (including undesired ones) between a library and its caller are greater than between an executable and its caller.
Posted Mar 8, 2007 22:00 UTC (Thu)
by ballombe (subscriber, #9523)
[Link] (5 responses)
Posted Mar 10, 2007 14:31 UTC (Sat)
by evgeny (subscriber, #774)
[Link] (4 responses)
Posted Mar 11, 2007 17:51 UTC (Sun)
by ekj (guest, #1524)
[Link] (3 responses)
True, true, one *could* do the former with a C-library, and the latter by piping to a setuid-executable, but most developers would probably consider the two funcitons related and prefer they both be accesses by the same mechanism.
Posted Mar 11, 2007 21:40 UTC (Sun)
by evgeny (subscriber, #774)
[Link] (2 responses)
In general, though, the locked-to-RAM pages are more or less a fiction. With the VM stuff entering our life, what an OS believes is RAM might actually be a swap in the host. Ditto for software/hardware suspend etc. All in all, I prefer a clean API over a mess with potential marginal extra security through the locked pages (and much less marginal chances of get screwed because of potential bugs in gpg being run setuid). Not to mention that e.g. ssh doesn't use mlock so ... why would one worry about gpg specifically?
Posted Mar 12, 2007 10:34 UTC (Mon)
by ekj (guest, #1524)
[Link]
Posted Mar 16, 2007 12:28 UTC (Fri)
by robbe (guest, #16131)
[Link]
Posted Mar 8, 2007 18:35 UTC (Thu)
by kingdon (guest, #4526)
[Link]
Posted Mar 9, 2007 3:32 UTC (Fri)
by pimlott (guest, #1535)
[Link] (1 responses)
This is a type error! Any reasonable type system, applied with a modicum of thought, would have prevented this flaw. Specifically, the verify function should be typed either to take a packet and return an output plus status, or to take a list of packets and return a list of outputs plus statuses (or something like that). If this were done, not only would the proper usage be more clear, but incorrect usage would fail harmlessly! But since gpg follows the unix approach of blob in, blob out, there's no way to catch the misuse.
The obvious objection is that gpg is a command-line interface, for sound technical reasons, so it can't be typed. We can imagine ways around this: Types could be added informally as documentation. This alone would clarify things for both gpg developers and users. Going further, the input and output could have an explicitly typed format that is checked when parsing. It breaks with tradition, but new thinking is called for here.
The fact that we use so many untyped (or badly typed) interfaces is a serious problem, causing us a whole lot of grief. We should recognize this, point it out when preventable flaws are discovered, and work to make typed interfaces more widely available and used. (Anybody following the next section of LWN knows that this approach is being applied to Linux with great results; too bad there aren't more Al Viros to go around.)
Posted Mar 9, 2007 6:45 UTC (Fri)
by njs (guest, #40338)
[Link]
FWIW, I have often pointed developers to GPGME as an example on how to use gpg in a proper way. Unfortunately I have fallen into the same pit as most other developers when I wrote GPGME. I simply got it wrong. So when applications using GPGME (e.g. KMail, Sylpheed and Mutt) are vulnerable, it is my fault.GnuPG signed message spoofing vulnerability
If GPG were written in a good style (here meaning separating the application and the core C API, with the latter being installed alongside the exec), most of clients would use that API directly, with such kinds of spoofing impossible. And the wrappers like GPGME (which internally calls the gpg executable) wouldn't be needed.GnuPG signed message spoofing vulnerability
Just noticed this in the gpg FAQ:GnuPG signed message spoofing vulnerability
>
> This has been frequently requested. However, the current viewpoint of the GnuPG maintainers is that this would lead to several security issues [...]
GnuPG signed message spoofing vulnerability
GPGP is setuid to be able to lock memory pages from being swapped to disk.GnuPG _is_ setuid
There is no need to worry about memory pages not being swapped to disk when verifying a signed message against a _public_ key...GnuPG _is_ setuid
True. But the very same users (be they people or mail-programs) that want to verify the integrity of a message using a public key frequently also wants to sign a message using a secret key.GnuPG _is_ setuid
Well, such functions may have e.g. insecure_ prefix added, and/or put into a separate header file so one makes an educated decision when using them.GnuPG _is_ setuid
True. There are good arguments in favour of just dropping whatever trickery requires setuid at the moment, in which case a library is unproblematic. I'm just saying, aslong as you *DO* want memory-locking, you're going to need an external app for atleast those parts. And if so, that external app may aswell do verification too, not only signing.GnuPG _is_ setuid
If you use your private key on a remote host (virtual or not) there are GnuPG _is_ setuid
more practical attack vectors. But best practise is to have the private
key only on a device in front of you -- in this case leakage to swap is a
concern. But suid-to-root is a stupid hack, better solutions are:
(a) allow mlock() for non-root users (I had a trivial kernel patch for
this ten years ago)
(b) no swap
(c) encrypted swap (what I use today)
I agree with the GnuPG developers that this is a bug, rather than just user error (or front-end error). The important part is: "they will see the contents of both of the plaintext packets followed by a statement that the signature was verified. Nothing in the output indicates the presence of two packets with different signature status." In other words, GnuPG had been claiming that something was verified when it was not.GnuPG signed message spoofing vulnerability
I have been tempted to post this response to many of the LWN security features, and it's kind of a rant, so I'm going to get it off my chest and not bring it up again. But I emphasize that it applies equally to a wide range of flaws, certainly to most cross-site scripting, SQL (or other sub-language) injection, command-line injection (like the Solaris telnet embarrassment), PHP variable insertion, and format string vulnerabilities. If developers were more aware of it, we might wipe out whole classes of problems that plague computer security today. (How's that for hype?)This is a type error
Sing it, sibling!This is a type error