Hacker News new | past | comments | ask | show | jobs | submit login

Let's summarize the situation:

Abstract: S/MIME and MUAs are broken. OpenPGP (with MDC) is not, but clients MUST check for GPG error codes. Use Mutt carefully or copy/paste into GPG for now.

- Some mail clients concatenate all parts of a multipart message together, even joining partial HTML elements, allowing the decrypted plaintext of an OpenPGP or S/MIME encrypted part to be exfiltrated via an image tag. Mail clients shouldn't be doing this in any world, and can fix this straightforwardly.

- S/MIME (RFC 5751) does not provide for authenticated encryption, so the ciphertext is trivially malleable. An attacker can use a CBC gadget to add the image tag into the ciphertext itself. We can't expect a mail client to avoid exfiltrating the plaintext in this case. S/MIME itself needs to be fixed (or abandoned).

- OpenPGP (RFC 4880) provides for authenticated encryption (called "MDC", see sections 5.13 and 13.11 of the RFC) which would prevent a similar CFB-based gadget attack if enforced. GPG added this feature in 2000 or 2001. If the MDC tag is missing or invalid, GPG returns an error. If GPG is asked to write the plaintext as a file, it will refuse. When the output is directed to a pipe, it will write the output and return an error code [1]. An application such as an MUA using it in this manner must check for the error code before rendering or processing the result. It seems this requirement was not made clear enough to implementors. The mail clients need to release patches to check for this error. This will create an incompatibility with broken OpenPGP implementations that have not yet implemented MDC.

- Even without clients enforcing or checking the authentication tag, it's a bit trickier to pull off the attack against OpenPGP because the plaintext may be compressed before encryption. The authors were still able to pull it off a reasonable percentage of the time. Section 14 of RFC 4880 actually describes a much earlier attack which was complicated in this same manner; it caused the OpenPGP authors to declare decompression errors as security errors.

Net-net, using encrypted email with Mutt is safe [2, Table 4], though even there, opening HTML parts encrypted with S/MIME in a browser is not, and double-checking how it handles GPG errors would be prudent before forking a browser on any OpenPGP encrypted parts. See the paper for other unaffected clients, including Claws (as noted below) and K-9 Mail (which does not support S/MIME). Otherwise, it's probably best to copy and paste into GPG (check the error code or ask it to write to a file) until this is worked out.

[1] https://lists.gnupg.org/pipermail/gnupg-users/2018-May/06031...

[2] https://efail.de/efail-attack-paper.pdf

“If GPG is asked to write the plaintext as a file, it will refuse. When the output is directed to a pipe, it will write the output and return an error code”

I honestly don’t care about the rationale, but this inconsistent behaviour is simply wrong. After 18 years of discussion, end this. Whenever DECRYPTION_FAIL occurs, there MUST be no decrypted content.

That's not really compatible with piped output. The encrypted message can't be authenticated until it has been completely processed, but the whole point of piping is to output bytes as soon as they're available.

Perhaps the moral of this story is to disable GPG's pipe feature? But it's a legitimate and significant performance improvement for authentic messages. You "just" have to remember to check the error code and it's fine/safe.

Perhaps that's just too much to ask. Maybe we just can't have fast streaming decryption because it's too hard for client developers to use safely. But that point of view is at least not obvious.

(On the other hand, what were you planning to do with the piped output in the first place? Probably render it, right? If GPG clients stream unauthenticated bytes into a high-performance HTML renderer, the result will surely be efail.)

That is not the whole point of piping, and the default behavior of GPG should be to buffer, validate the MDC, and release plaintext only after it's been authenticated. Pipes are a standardized Unix interface between processes, not a solemn pledge to deliver bytes as quickly as possible.

If pipes had the connotation you claim they do, it would never be safe to pipe ciphertext, because the whole goal of modern AEAD cryptography is never to release unauthenticated plaintext to callers.

Clients encrypting whole ISO images should expect that decryption will require a non-default flag. Ideally, GPG would do two-pass decryption, first checking the MDC and then decrypting. Either way, the vast, commanding majority of all messages GPG ever processes --- in fact, that the PGP protocol processes --- should be buffered and checked.

If you have a complaint about how unwieldy this process is, your complaint is with the PGP protocol. The researchers, and cryptographers in general, agree with you.

Is it so easy for GPG to buffer the cleartext while validating the MDC? As the cleartext may not fit in RAM, this means that GPG could need to write it to a temporary file, right? But then, if decryption is aborted messily (e.g., the machine loses power), then this means that GPG would be leaving a file with part of the cleartext behind, which has obvious security implications.

You could also imagine a two-pass approach where you first verify and then decrypt, but then what about a timing attack where a process would be modifying the encrypted file between the two passes?

It doesn't look so easy to solve this problem -- arguably the right way would be to change the design of the OpenPGP protocol, cf https://www.imperialviolet.org/2014/06/27/streamingencryptio...

Again, the cleartext virtually always fits trivially in RAM, and when it doesn't, it can error out and require a flag to process. Yes, this is easy to fix.

OpenPGP needs to change as well, but that doesn't make insecure behavior acceptable in the interim, no matter what Werner Koch thinks.

What is the point of piping, in your view? My understanding is that it's a stream of bytes with backpressure, designed specifically to minimize buffering (by pausing output when downstream receivers are full/busy).

> If pipes had the connotation you claim they do, it would never be safe to pipe ciphertext, because the whole goal of modern AEAD cryptography is never to release unauthenticated plaintext to callers.

You say that like it's a reductio ad absurdum, but I think that's essentially right; you can't do backpressure with unauthenticated ciphertext. You have to buffer the entire output to be sure that it's safe for further processing.

Thus, if you want to buffer the entire output, don't use a pipe; ask the tool to generate a file, and then read the file only when the process says that the file is done and correct.

(I'd say that's a lot more wieldy than two-pass decryption.)

Based on your other remarks about PGP, (nuke it from orbit) I'm not sure you have any constructive remarks to make on how to improve GPG, but I guess making it two-pass by default (with a --dangerous-single-pass flag) would be an improvement.

For normal size emails, users probably wouldn't notice the performance cost of the second pass, and clients who care about performance at that level can opt into single-pass decryption and just promise to check the error code.

You know sort works with pipes, right? It doesn't squirt out mostly sorted output whenever it feels like it.

Backpressure is a feature of Unix pipes. It isn't their raison d'être.

I don't care how you implement it, but any claim that you can't check the MDC in GPG because it's a piped interface is obviously false. GPG can, like any number of Unix utilities, some casually written and some carefully written, simply buffer the data, process it, and write it.

Nobody said "you can't check the MDC." Everybody said "you have to check GPG's error code."

And I think it's clear to everybody (in this thread) that GPG's approach is a dangerous blame-the-user approach to API design, even granting that this dangerous approach offers optimum performance (especially relative to adding an entire second pass).

There's no difference. You're talking about the program, I'm talking about the mechanism. Either way:

* GPG should never release unauthenticated plaintext to callers. The exit code is a red herring.

* Nothing about "pipes" prevents them from squelching unauthenticated plaintext.

You are getting your concepts confused. Pipes are one thing, but the concept at hand is in fact filters, programs that primarily read data from their standard inputs and write other (processed) data to their standard outputs. What pipes involve is a red herring, because filters do not necessitate pipes. Filters have no requirements that they write output whilst there is still input to be read, and several well-known filter programs indeed do not do that.

This is why I initially hesitated to implement a streaming interface for my crypto library¹ (authenticated encryption and signatures). I eventually did it, but felt compelled to sprinkle the manual with warnings about how streaming interfaces encourage the processing of unauthenticated messages.

Now that we have a vulnerability with a name, I think I can make those warning even scarier. I'll update that manual.

[1]: https://monocypher.org/

Isn't it possible to adjust any existing authentication scheme to authenticate block-by-block?

> Use Mutt carefully or copy/paste into GPG for now.

According to [1], Claws Mail is also unaffected. I don't know if it was tested with or without its HTML plugin, but this should make no difference as long as the plugin is not configured to access remote resources. (By default it can not make network requests.)


OK, so Thunderbird plus Enigmail is probably most popular in Linux. And according to Robert J. Hansen:[0]

> By default, GnuPG will scream bloody murder if a message lacks an MDC or if the MDC is invalid. At that point it's up to your email client to pay attention to the warning and do the right thing. Enigmail 2.0 and later are fine, but I can't speak for other systems.

So if you use Enigmail, do make sure that you're not at v1.99. Just get the add-on in Thunderbird.

Also, of course, make sure that external resources aren't being fetched.

0) https://lists.gnupg.org/pipermail/gnupg-users/2018-May/06032...

Edit: Oh, but damn. There's more in that thread. Enigmail >v2 can be forced to decrypt with MDC missing.[1] And this is a gpg bug:[2]

> ... and Patrick, moving faster than the speed of light, already has the bug triaged and bounced back. This is actually a GnuPG bug, not an Enigmail bug. ...


> It's worth noting, incidentally, the #Efail attack flat-out requires MIME. So inline PGP messages are not vulnerable, as there's no MIME parsing pass which can be exploited. So you're still safe, although this is still a bug that should be fixed. ;)

I also saw something about it requiring HTML decoding, but can't find it again :(

1) https://lists.gnupg.org/pipermail/gnupg-users/2018-May/06032...

2) https://lists.gnupg.org/pipermail/gnupg-users/2018-May/06032...

3) https://lists.gnupg.org/pipermail/gnupg-users/2018-May/06032...

More: Yes, disable HTML rendering. In Thunderbird, select "/ View / Message Body As / Plain Text".


> The EFAIL attacks break PGP and S/MIME email encryption by coercing clients into sending the full plaintext of the emails to the attacker. In a nutshell, EFAIL abuses active content of HTML emails, for example externally loaded images or styles, to exfiltrate plaintext through requested URLs. To create these exfiltration channels, the attacker first needs access to the encrypted emails, for example, by eavesdropping on network traffic, compromising email accounts, email servers, backup systems or client computers. The emails could even have been collected years ago.

So basically, 1) the attacker embeds a link to the encrypted message, 2) the email client fetches and decrypts it, and then 3) sends plaintext back to the attacker.

4) https://lists.cpunks.org/pipermail/cypherpunks/2018-May/0421...

> So basically, 1) the attacker embeds a link to the encrypted message, 2) the email client fetches and decrypts it, and then 3) sends plaintext back to the attacker.

What? The attacker embeds secure content inside a link, not a link to the content. It could come from files stored in a public place or emails.


Check RFC2634 before you abandon S/MIME. Triple wrapping solves surreptitious forwarding, which is how this attack works. Sadly AFAIK it's implemented only in Trustedbird.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact