CVE-2020-11072 (published 2020-05-12T01:15Z)

In SLP Validate (npm package slp-validate) before version 1.2.1, users could experience false-negative validation outcomes for MINT transaction operations. A poorly implemented SLP wallet could allow spending of the affected tokens which would result in the destruction of a user's minting baton. This has been fixed in slp-validate in version 1.2.1. Additonally, slpjs version 0.27.2 has a related fix under related CVE-2020-11071.

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

Weakness information:
cwe_id: CWE-697
cwe_name: Incorrect Comparison
description: The product compares two entities in a security-relevant context, but the comparison is incorrect, which may lead to resultant weaknesses.
extended_description: 
            This Pillar covers several possibilities:
               
                  the comparison checks one factor incorrectly;
                  the comparison should consider multiple factors, but it does not check at least one of those factors at all;
                  the comparison checks the wrong factor.
               
         
         

Fix information:
repo_url: https://github.com/simpleledger/slp-validate
commit_details: repo_url: https://github.com/simpleledger/slp-validate
author: James Cramer
author_date: 2020-04-29 09:52:56-04:00
msg: fix false negative case for MINT transactions

See the newly added unit test case for this issue.
Currently there are 151 unit tests.
repository: repo_url: https://github.com/simpleledger/slp-validate
repo_name: simpleledger/slp-validate.js
description: SLP validator with pre-broadcast validation and burn protection.
repo_language: TypeScript
owner: simpleledger
file_changes: filename: validation.ts
change_type: ModificationType.MODIFY
diff: @@ -408,10 +408,10 @@ export class ValidatorType1 {
                     }
                 } catch (_) { }
             }
-            if (validation.parents.length !== 1) {
+            if (validation.parents.length < 1) {
                 validation.validity = false;
                 validation.waiting = false;
-                validation.invalidReason = "MINT transaction must have 1 valid baton parent.";
+                validation.invalidReason = "MINT transaction must have at least 1 candidate baton parent input.";
                 return validation.validity!;
             }
         } else if (slpmsg.transactionType === SlpTransactionType.SEND) {
@@ -468,10 +468,14 @@ export class ValidatorType1 {
         // Set validity validation-cache for parents, and handle MINT condition with no valid input
         // we don't need to check proper token id since we only added parents with same ID in above steps.
         const parentTxids = [...new Set(validation.parents.map(p => p.txid))];
-        for (let i = 0; i < parentTxids.length; i++) {
-            const valid = await this.isValidSlpTxid({ txid: parentTxids[i] });
-            validation.parents.filter(p => p.txid === parentTxids[i]).map(p => p.valid = valid);
-            if (validation.details!.transactionType === SlpTransactionType.MINT && !valid) {
+        for (const id of parentTxids) {
+            const valid = await this.isValidSlpTxid({ txid: id });
+            validation.parents.filter(p => p.txid === id).map(p => p.valid = valid);
+        }
+
+        // Check MINT for exactly 1 valid MINT baton
+        if (validation.details!.transactionType === SlpTransactionType.MINT) {
+            if (validation.parents.filter(p => p.valid && p.inputQty === null).length !== 1) {
                 validation.validity = false;
                 validation.waiting = false;
                 validation.invalidReason = "MINT transaction with invalid baton parent.";

programming_language: TypeScript