From 7ff658b7c949b25799e26644316b7116ec68e1bf Mon Sep 17 00:00:00 2001 From: Arya Rizky Date: Fri, 5 Jun 2026 23:10:24 +0700 Subject: [PATCH] fix(isCreditCard): fix Mastercard regex anchoring bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Mastercard regex had a regex operator precedence bug due to unanchored alternation. The pattern: /^5[1-5][0-9]{2}|(222[1-9]|...)[0-9]{12}$/ Due to | having lower precedence than ^ and $, this parsed as: 1. ^5[1-5][0-9]{2} (start-anchored only — matches any string starting with 51XX-55XX regardless of length) 2. (222[1-9]|...)[0-9]{12}$ (end-anchored only) This caused isCreditCard to return true for partial strings like '5108' and short 4-digit inputs. Fixed by wrapping the alternation in a non-capturing group with both anchors outside: ^(?:5[1-5][0-9]{14}|...)$ Closes #2717 --- src/lib/isCreditCard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/isCreditCard.js b/src/lib/isCreditCard.js index 938679d39..950c8c30c 100644 --- a/src/lib/isCreditCard.js +++ b/src/lib/isCreditCard.js @@ -6,7 +6,7 @@ const cards = { dinersclub: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/, discover: /^6(?:011|5[0-9][0-9])[0-9]{12,15}$/, jcb: /^(?:2131|1800|35\d{3})\d{11}$/, - mastercard: /^5[1-5][0-9]{2}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/, // /^[25][1-7][0-9]{14}$/; + mastercard: /^(?:5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12})$/, unionpay: /^(6[27][0-9]{14}|^(81[0-9]{14,17}))$/, visa: /^(?:4[0-9]{12})(?:[0-9]{3,6})?$/, };