Vendor Description
“This project aims to provide an Open Source OpenPGP library in JavaScript so it can be used on virtually every device. Instead of other implementations that are aimed at using native code, OpenPGP.js is meant to bypass this requirement (i.e. people will not have to install gpg on their machines in order to use the library). The idea is to implement all the needed OpenPGP functionality in a JavaScript library that can be reused in other projects that provide browser extensions or server applications. It should allow you to sign, encrypt, decrypt, and verify any kind of text – in particular e-mails – as well as managing keys.”
Source: https://openpgpjs.org
Business Recommendation
SEC Consult was tasked by the German Bundesamt für Sicherheit in der Informationstechnik (BSI) with conducting a security audit of the Mailvelope browser extension as well as the parts of OpenPGP.js used by Mailvelope. During the course of this audit multiple security vulnerabilities with severities ranging from minor to critical have been identified. Some of the vulnerabilities with higher severity are published as an advisory. A more detailed description of the vulnerabilities as well as a description of other vulnerabilities found during this project can be found in the report that has been made available by the BSI:
Vulnerability Overview/description
1) Message Signature Bypass (CVE-2019-9153)
OpenPGP defines several types of signatures with each type carrying a different semantic. Signatures are implemented as packets and each signature packet can contain subpackets.
To indicate a message signature (e.g. a signed e-mail), the signature type “text” is used. The text signature packet verifies both its subpackets as well as the signed text.
During verification of a message signature, OpenPGP.js does not verify that the signature is of type text. An attacker could therefore construct a message that, instead of a text signature, contains a signature of another type. As the input required for the verification process depends on the signature type, an attacker could use a signature with a type that only verifies its subpackets and does not require additional input.
An attacker could construct a message that contains a valid “standalone” or “timestamp” signature packet signed by another person. OpenPGP.js would incorrectly assume this message to be signed by that person.
2) Information from Unhashed Subpackets is Trusted (CVE-2019-9154)
OpenPGP signature subpackets contain information related to a signature (e.g. the creation timestamp). These subpackets may appear in a “hashed” and “unhashed” subpacket container. While the information in the hashed subpackets is signed, the unhashed subpackets are not cryptographically protected. OpenPGP.js however does not distinguish between these subpackets. When parsing a signature packet, the signed information is parsed first. When the unhashed packets are read, the information from the hashed packets is overwritten.
An attacker could arbitrarily modify the contents of e.g. a key certification signature or revocation signature. As a result, the attacker could e.g. convince a victim to use an obsolete key for encryption.
3) Invalid Curve Attack (CVE-2019-9155)
The implementation of the Elliptic Curve Diffie-Hellman (ECDH) key exchange algorithm does not verify that the communication partner’s public key is valid (i.e. that the point lies on the elliptic curve). This causes the application to implicitly calculate the resulting secret key not based on the specified elliptic curve but rather an altered curve. By carefully choosing multiple altered curves (and therefore the resulting public key), and observing whether decryption fails, an attacker can extract the victim’s private key.
This attack requires the attacker to be able to provide multiple manipulated messages and to observe whether decryption fails.
Proof Of Concept
1) Message Signature Bypass (CVE-2019-9153)
The script message_signature_bypass.js (see below) demonstrates this issue. The function fakeSignature reads a signed message and replaces its content. It then replaces the signature with a standalone signature of the victim.
Source code (SEC_Consult_BSI_Mailvelope-signature_bypass.js)
2) Information from Unhashed Subpackets is Trusted (CVE-2019-9154)
The script unsigned_subpackets.js demonstrates this issue. It parses an expired key and adds additional unhashed subpackets that specify a different key expiration. When this newly-created key is parsed, it can be used for encrypting messages.
Source code (SEC_Consult_BSI_Mailvelope-unsigned_subpackets.js)
3) Invalid Curve Attack (CVE-2019-9155)
The script in invalid_curve_attack.js demonstrates this issue. Note that since OpenPGP uses only the x-coordinate of the secret point, the oracle succeeds both when it calculates the same point as the attacker or when it calculates its inverse point. Therefore, the Chinese Remainder Theorem cannot be directly applied to the result. Instead, the script demonstrates that the remainders of the private key matches the corresponding gathered remainder. In order to fully implement this attack, an attacker could verify the results using other public key points with a non-prime order.
Source code (SEC_Consult_BSI_Mailvelope-invalid_curve_attack.js)
Vulnerable / Tested Versions
The version 4.1.2 was found to be vulnerable. The Invalid Curve attack is also viable against version 4.2.0.
Vendor Contact Timeline
Vendor communication was conducted by the BSI as well as their contractors.
Solution
Upgrade to the latest version of OpenPGP.js.
Workaround
None.
Advisory URL
https://www.sec-consult.com/en/vulnerability-lab/advisories/index.html
EOF Wolfgang Ettlinger / @2019