Skip to content

discover() and jcb() accept card numbers from outside their issuer's IIN ranges #566

Open

Description

@rahul05ranjan

discover() and jcb() accept card numbers from outside their issuer's IIN ranges

The prefix patterns in card.py are broader than the actual issuer identification number ranges, so Luhn-valid numbers issued by other networks are reported as valid Discover / JCB cards.

Repro (on current master, 22786cc):

from validators import card_number, discover, jcb

# All of these are Luhn-valid and pass validators.discover(),
# but their IINs do not belong to Discover:
print(discover("6020000000000003"))  # True — 6020 is not Discover
print(discover("6040000000000009"))  # True — 6040 is not Discover
print(discover("6400000000000003"))  # True — 6400 is not Discover
print(discover("6411000000000000"))  # True — 6411 is not Discover

# These pass validators.jcb(), but JCB IINs are 3528–3589:
print(jcb("3500000000000009"))       # True — 3500 is outside 3528–3589
print(jcb("3590000000000000"))       # True — 3590 is outside 3528–3589

What the prefixes should be

Discover's IIN ranges are 6011, 644–649 and 65 (plus the 622126–622925 UnionPay co-branded block). The current pattern ^(60|64|65) accepts every 60xx/64xx BIN, which also belong to other networks — for example GPN uses 60–63, UkrCart uses 60400100–60420099, RuPay uses 60, and 640–643 are not in Discover's range either.

JCB's IIN range is 3528–3589, but the pattern is ^35, which also accepts 3500–3527 and 3590–3599.

Possible patterns:

discover: r"^(6011|64[4-9]|65)"
jcb:      r"^35(2[89]|[3-7][0-9]|8[0-9])"

Context

This is the same class of problem that #467 fixed for mastercard() ("no longer accepts non-Mastercard 2-series BINs"), and both existing examples in the docstring (6011111111111117, 3566002020360505) still validate with the tightened patterns, as do the test values in open PR #546 (6011000990139424, 6445644456445, 3530111333300000, 3566002020360505).

For a form-validation use case the impact is real: e.g. a Ukrcart/GPN 60xx card number entered into a "Discover card" field passes validators.discover() but will be declined by any payment processor.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions