CVE-2019-16930 (published 2019-09-28T22:15Z)

Zcashd in Zcash before 2.0.7-3 allows discovery of the IP address of a full node that owns a shielded address, related to mishandling of exceptions during deserialization of note plaintexts. This affects anyone who has disclosed their zaddr to a third party.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:P/I:N/A:N)
CVSS v3 base score: 5.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: CWE-755
cwe_name: Improper Handling of Exceptional Conditions
description: The product does not handle or incorrectly handles an exceptional condition.
extended_description: 
            
         
         

Fix information:
repo_url: https://github.com/zcash/zcash
commit_details: repo_url: https://github.com/zcash/zcash
author: Jack Grigg
author_date: 2019-09-19 18:25:09+01:00
msg: Ignore exceptions when deserializing note plaintexts
repository: repo_url: https://github.com/zcash/zcash
repo_name: zcash/zcash
description: Zcash - Internet Money
repo_language: C++
owner: zcash
file_changes: filename: Note.cpp
change_type: ModificationType.MODIFY
diff: @@ -173,15 +173,21 @@ boost::optional<SaplingOutgoingPlaintext> SaplingOutgoingPlaintext::decrypt(
     }
 
     // Deserialize from the plaintext
-    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
-    ss << pt.get();
+    try {
+        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+        ss << pt.get();
 
-    SaplingOutgoingPlaintext ret;
-    ss >> ret;
+        SaplingOutgoingPlaintext ret;
+        ss >> ret;
 
-    assert(ss.size() == 0);
+        assert(ss.size() == 0);
 
-    return ret;
+        return ret;
+    } catch (const boost::thread_interrupted&) {
+        throw;
+    } catch (...) {
+        return boost::none;
+    }
 }
 
 boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
@@ -197,13 +203,17 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
     }
 
     // Deserialize from the plaintext
-    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
-    ss << pt.get();
-
     SaplingNotePlaintext ret;
-    ss >> ret;
-
-    assert(ss.size() == 0);
+    try {
+        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+        ss << pt.get();
+        ss >> ret;
+        assert(ss.size() == 0);
+    } catch (const boost::thread_interrupted&) {
+        throw;
+    } catch (...) {
+        return boost::none;
+    }
 
     uint256 pk_d;
     if (!librustzcash_ivk_to_pkd(ivk.begin(), ret.d.data(), pk_d.begin())) {
@@ -243,11 +253,17 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
     }
 
     // Deserialize from the plaintext
-    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
-    ss << pt.get();
-
     SaplingNotePlaintext ret;
-    ss >> ret;
+    try {
+        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+        ss << pt.get();
+        ss >> ret;
+        assert(ss.size() == 0);
+    } catch (const boost::thread_interrupted&) {
+        throw;
+    } catch (...) {
+        return boost::none;
+    }
 
     uint256 cmu_expected;
     if (!librustzcash_sapling_compute_cm(
@@ -265,8 +281,6 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
         return boost::none;
     }
 
-    assert(ss.size() == 0);
-
     return ret;
 }
 

programming_language: C++