Summary: | Decryption Oracle based on replying to PGP or S/MIME encrypted emails | ||
---|---|---|---|
Product: | [Applications] kmail2 | Reporter: | Jens Mueller <jens.a.mueller+kde> |
Component: | crypto | Assignee: | kdepim bugs <kdepim-bugs> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | aacid, asturm, beuc, dvratil, faure, montel, nate, null+samzain, rdieter, sknauss, stupor_scurvy343 |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Debian stable | ||
OS: | Linux | ||
Latest Commit: | https://commits.kde.org/messagelib/ac360b3a57eacbf0542ed0800e6054db76f01398 | Version Fixed In: | 5.11.2 |
Sentry Crash Report: | |||
Attachments: |
Proof-of-concept PGP
Proof-of-concept S/MIME html mail with two images embeded. |
Description
Jens Mueller
2019-02-22 12:52:18 UTC
Created attachment 118288 [details]
Proof-of-concept PGP
Created attachment 118289 [details]
Proof-of-concept S/MIME
In KMail this attack requires that user would enable "Automatic decryption of encrypted messages when viewing" option in KMail settings, which is disabled by default. Without this option enabled the user has to click on "Decrypt" on the part that the attacker wants to leak. At this point, the user will still clearly see which part of the content was encrypted and which part was not. When the user wants to reply to this decrypted message, the content would indeed get leaked to the attacker. However, I believe that at this point KMail has done enough to prevent (by not enabling auto-decryption by default) and warn (by clearly showing which part is encrypted and which not) the user so he or she could judge for themselves the potential risks when replying to the message. Things may have changed in the meantime, but for the version we tested (v5.2.3), there is no need to click on "Decrypt Message". While the plaintext is not shown to the user, if he does not explicitly click "Decrypt Message", the plaintext is still included in replies -- just re-tested for S/MIME and PGP/MIME. Note that KMail was tested in the default settings (the option "Attempt decryption of encrypted messages when viewing" was *not* set). (In reply to Daniel Vrátil from comment #3) > In KMail this attack requires that user would enable "Automatic decryption > of encrypted messages when viewing" option in KMail settings, which is > disabled by default. As Jens already explained, this setting does not help here. This Setting only do not trigger decryption directly when you view the mail. But if you reply the mail is decrypted in anycase. And we use the same code paths for rendering the view and prepare the reply/forward. I am not sure I understand where the problem is, potentially means you need to explain it in simpler words (or that i need to learn how to read long sentences :D) Is this problem? * A sends encrypted email to B * C intercepts that email * C resends the email modified to B (adding his own reply address and some plain text) * B answers to C * C can see the original email Exactly that's the problem. Note that not only one message, but hundreds of captured messages can be wrapped and leaked with one single reply. Traditional message takeover attacks under a new identity (C) are considered as an acceptable risk in email e2e encryption because it is assumed that given the context of the message (e.g.,“Hi A, [...] Yours, B”) B can tell that this message is not originally from C and could easily discover the deception. However, using MIME wrapping, C can make a different content being displayed to B (if B does not carefully scroll down the whole message conversation) and therefore potentially trick B into replying to C. Right i can see the problem. Question is, are those kind of messages that you are suggesting to stop supporting "common" or even is there a reason for someone to be sending messages like that? Or if you get a message like this it's most probably someone trying to trick you? Because if those messages are common, stopping to work on them is going to be a pain for the people that have a valid usecase. Imho, there are no legitimate use cases for `partial encryption` in S/MIME and PGP/MIME, but it's hard to measure if such emails do exist in the wild. In case of PGP/Inline, unfortunately, every part is encrypted separately. Note that a captured PGP/MIME message can be `downgraded` to be interpreted in the context of PGP/INLINE. Update: Here's a full (public) report on the issue: https://arxiv.org/ftp/arxiv/papers/1904/1904.07550.pdf For KMail, CVE-2019-10732 was assigned for reply-based `decryption oracles`. Interesting problem. Here's my feedback. - Preventing KMail from *sending* such messages would obviously be no help (one could just craft that message by hand or using another email client). - Preventing the user from replying to such a message would be very weird user experience (sorry, you are not allowed to reply to this message!) - So I guess the best solution is that when replying, we don't decrypt parts that were encrypted in the original message. I.e. if we are replying with a copy of those parts, and they were encrypted, they should be copied "as is". This would prevent any newly-added recipient from reading those, but that's fair enough I would say. I wouldn't really know how to implement this though. Might be tricky if the tree in memory only has the decrypted version. - Alternatively, KMail could say "for security reasons, these parts are going to be removed from your reply". But this also requires that we somehow know that these parts used to be encrypted in the original email. About the original suggestion: "Do not decrypt emails unless the PGP or S/MIME encrypted part is the root node -- and therefore the only part -- in the MIME tree (exception: multipart/signed for encrypted-then-signed S/MIME messages)." This would mean if you attach a non-encrypted image (say, company logo) to an encrypted email, the recipient can't reply to the email anymore? I think we always want to decrypt the main text part? (fuzzy term, I don't know what the actual logic is in kmail, but I mean the text that gets quoted). @Jens: what version did you test? You set "Debian Stable" and "5.10.3" this does not match. Debian stable has 16.04.3 aka 5.2.3. I now started to look into the issue, but I can't reproduce it with the attached messages for 18.08.3 nor for master. At least for the encrypted content to be simple text. Do I need to construct a mimetree inside the encrypted message parts? And this make totally sense, as we have already have the concept of firstTextNode inside ObjectTreeParser, that takes effect here. I added the proof-of-concept mails to our autotests: https://phabricator.kde.org/D20757 the plain.reply files are the output of the reply window. For those you have a test environment for messagelib, those can view such mails and reply/forward: GNUPGHOME=<buildpath of messagelib>/messagecore/autotests/gnupg_home/ kmail --view 404698-gpg.mbox A short explanation, how a reply/forward is created (everything in messagelib): * templateparser/src/templateparserjob constructs a new KMime::Message mMsg from a given mOrigMsg. * TemplateParserJob uses MimeTreeParser::ObjectTreeParser to get htmlContent/plainTextContent. At least for plainTextContent it is easy to follow, that only the content from first text node is used. For htmlContent it looks, like we merge different htmlNodes via messagepart.cpp:HtmlMessagePart::fix() (In reply to David Faure from comment #11) > - Preventing KMail from *sending* such messages would obviously be no help > (one could just craft that message by hand or using another email client). ACK. > - Preventing the user from replying to such a message would be very weird > user experience (sorry, you are not allowed to reply to this message!) jepp bad UX. > - So I guess the best solution is that when replying, we don't decrypt parts > that were encrypted in the original message. I.e. if we are replying with a > copy of those parts, and they were encrypted, they should be copied "as is". > This would prevent any newly-added recipient from reading those, but that's > fair enough I would say. > I wouldn't really know how to implement this though. > Might be tricky if the tree in memory only has the decrypted version. > > - Alternatively, KMail could say "for security reasons, these parts are > going to be removed from your reply". But this also requires that we somehow > know that these parts used to be encrypted in the original email. Both things are not that hard to solve. We have MimeTreeParser::ObjecttreeParser that returns a MessagePart tree. This is a tree, where only visual interesting nodes of the Mime messages with the additional information of each node, about their encrypted status, used keys etc... To get an idea about those trees look at mimetreeparser/autotests/data/*tree files, these are the MessagePart tree for the corresponding mbox. Also TemplateParser, that is responsible for creating a reply/template, uses MimeTreeParser::ObjecttreeParser, so we are able to filter out bad nodes. @David: This would mean if you attach a non-encrypted image to an encrypted... Absolutely, such an email could not be decrypted anymore if you follow our suggestions (or had to be manually decrypted on the command line). While this may seem a bit harsh, we have not seen any mail client that allows to send such "partially encrypted" emails (e.g., with unencrypted attachments), and I think handling such edge cases can become a security nightmare. Either the whole mail is encrypted or it's not, everything else gives a false sense of security, imho. However, I see the developer's perspective and the and the fear of potentially breaking things, too. I guess a rule like "in case of an encrypted, multipart email, reply only with the first part" *should* be fine too. @Sandro: We originally tested in version 5.2.3 on Debian 9.8 (stretch). This version is probably outdated by now. (In reply to Jens Mueller from comment #15) > @David: This would mean if you attach a non-encrypted image to an > encrypted... > > Absolutely, such an email could not be decrypted anymore if you follow our > suggestions (or had to be manually decrypted on the command line). While > this may seem a bit harsh, we have not seen any mail client that allows to > send such "partially encrypted" emails (e.g., with unencrypted attachments), > and I think handling such edge cases can become a security nightmare. Either > the whole mail is encrypted or it's not, everything else gives a false sense > of security, imho. One client that supports sending encrypted mails with unencrypted attachment is kmail (but you need to do it explicitly). One common use case, of such partial encrypted mails are mails forwarded via Mailman. Mailman adds a non encrypted footer to each email. So not supporting these mails make would break my workflow. This was the reason, why I fixed a several things, because I didn't wanted to see this footer in the reply ;D And I see a big difference between displaying such broken mails and replying. > However, I see the developer's perspective and the and the fear of > potentially breaking things, too. I guess a rule like "in case of an > encrypted, multipart email, reply only with the first part" *should* be fine > too. I think so, too, that reply to only one part you be fine. > @Sandro: We originally tested in version 5.2.3 on Debian 9.8 (stretch). This > version is probably outdated by now. yes! Did you tested any other version? Git commit d397aa46e809203c94e31891caac57affac746d9 by Sandro Knauß. Committed on 12/05/2019 at 20:34. Pushed by knauss into branch 'Applications/19.04'. Test mails for Decryption Oracle based on replying to PGP or S/MIME. Summary: In order to make sure we never add a Decryption Oracle add test mails to TemplateParser. Reviewers: #kde_pim, aacid, dfaure Subscribers: kde-pim Tags: #kde_pim Differential Revision: https://phabricator.kde.org/D20757 A +120 -0 templateparser/autotests/data/404698-gpg.mbox A +51 -0 templateparser/autotests/data/404698-gpg.mbox.plain.reply A +88 -0 templateparser/autotests/data/404698-smime.mbox A +51 -0 templateparser/autotests/data/404698-smime.mbox.plain.reply https://commits.kde.org/messagelib/d397aa46e809203c94e31891caac57affac746d9 Created attachment 120026 [details]
html mail with two images embeded.
There is one question, how we should handle forwards with embedded images.
We have a testcase with two images embedded (see attachment), that are added to the forwarded message. IMO this is not a security issue, as we do not parse those two images (aka do not encrypt them) and just copy them like they were sent over the wire. So we can't leak private information.
Git commit a58286aec8f300d78c570726924baa91d9a22771 by Sandro Knauß. Committed on 12/05/2019 at 21:48. Pushed by knauss into branch 'Applications/19.04'. Merge branch 'CVE-2019-10732' into Applications/19.04 Fixes the CVE-2019-10732, with additional tests, to make sure, we fixed the CVE completely. FIXED-IN: 5.11.2 CCMAIL: security@kde.org https://commits.kde.org/messagelib/a58286aec8f300d78c570726924baa91d9a22771 Git commit 8f9b85b664be0987014c5d2485e706ab5a198e1b by Sandro Knauß. Committed on 12/05/2019 at 20:37. Pushed by knauss into branch 'Applications/19.04'. Make unexpected data leak harder via reply. ObjectTreeParser.htmlContent/plainTextContent may concats different encrypted parts without the user noticing it. That would lead to a Decryption oracle. We have already a logic to find the topleveltextNode in MimeTreeParser, this does not take HTML nodes into account nor that TEXT nodes may have several PGP Inline blocks. That plaintextContent for HtmlMessagePart is not return QString(), that bubbled up by testing the stuff. M +5 -0 mimetreeparser/src/messagepart.cpp M +1 -0 mimetreeparser/src/messagepart.h A +31 -0 templateparser/autotests/data/openpgp-inline-space.mbox A +1 -0 templateparser/autotests/data/openpgp-inline-space.mbox.html.reply A +1 -0 templateparser/autotests/data/openpgp-inline-space.mbox.plain.reply M +46 -14 templateparser/src/templateparserjob.cpp https://commits.kde.org/messagelib/8f9b85b664be0987014c5d2485e706ab5a198e1b Git commit ac360b3a57eacbf0542ed0800e6054db76f01398 by Sandro Knauß. Committed on 12/05/2019 at 20:37. Pushed by knauss into branch 'Applications/19.04'. Decryption Oracle based on forwarding PGP or S/MIME mails (CVE-2019-10732) Summary: Add test coverage for mail forwarding. Test Plan: all tests passes forward (text/html): [x] PGP Mime text [x] PGP Mime html [x] S/MIME [x] PGP inline Reviewers: #kde_pim, vkrause, aacid, dfaure Subscribers: kde-pim, security-team Tags: #kde_pim Differential Revision: https://phabricator.kde.org/D20847 A +72 -0 templateparser/autotests/data/404698-gpg-attachments.mbox A +66 -0 templateparser/autotests/data/404698-gpg-attachments.mbox.forwarded.mbox A +1 -0 templateparser/autotests/data/404698-gpg-attachments.mbox.html.reply A +5 -0 templateparser/autotests/data/404698-gpg-attachments.mbox.plain.reply A +83 -0 templateparser/autotests/data/html-attachment1 [details].mbox.forwarded.mbox A +28 -0 templateparser/autotests/data/html-attachment2 [details].mbox.forwarded.mbox M +162 -0 templateparser/autotests/templateparserjobtest.cpp M +9 -0 templateparser/autotests/templateparserjobtest.h https://commits.kde.org/messagelib/ac360b3a57eacbf0542ed0800e6054db76f01398 Hi, As part of the Debian LTS project, I'm trying to fix this vulnerability in Debian Jessie, which ships kdepim 4.14.1. I'm attempting to backport https://commits.kde.org/messagelib/8f9b85b664be0987014c5d2485e706ab5a198e1b but the API is very different, I'm not even sure there are available functions to expose the MIME parts and extract their quotable content independently. Do you think this is doable? I wrote something cruder but that works with the 404698-* messagelib test cases: https://www.beuc.net/tmp/kdepim-CVE-2019-10732.patch This should be a good compromise, let me know if I missed something. I plan to upload an update shortly, probably next week :) (In reply to beuc from comment #23) > I wrote something cruder but that works with the 404698-* messagelib test > cases: > https://www.beuc.net/tmp/kdepim-CVE-2019-10732.patch > This should be a good compromise, let me know if I missed something. > I plan to upload an update shortly, probably next week :) The code looks like it should be enough. But the surrounding code has changed a lot between 4.14.1 and had less tests etc. It may be that there are other things to fix. |