VYPR
High severityNVD Advisory· Published Nov 27, 2025· Updated Jan 29, 2026

CVE-2025-12758

CVE-2025-12758

Description

Versions of the package validator before 13.15.22 are vulnerable to Incomplete Filtering of One or More Instances of Special Elements in the isLength() function that does not take into account Unicode variation selectors (\uFE0F, \uFE0E) appearing in a sequence which lead to improper string length calculation. This can lead to an application using isLength for input validation accepting strings significantly longer than intended, resulting in issues like data truncation in databases, buffer overflows in other system components, or denial-of-service.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
validatornpm
< 13.15.2213.15.22

Affected products

1

Patches

1
d457ecaf55b0

fix(isLength): correctly handle Unicode variation selectors (#2616)

https://github.com/validatorjs/validator.jsKarol WrótniakNov 5, 2025via ghsa
3 files changed · +145 98
  • src/lib/isLength.js+1 1 modified
    @@ -14,7 +14,7 @@ export default function isLength(str, options) {
         max = arguments[2];
       }
     
    -  const presentationSequences = str.match(/(\uFE0F|\uFE0E)/g) || [];
    +  const presentationSequences = str.match(/[^\uFE0F\uFE0E][\uFE0F\uFE0E]/g) || [];
       const surrogatePairs = str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || [];
       const len = str.length - presentationSequences.length - surrogatePairs.length;
       const isInsideRange = len >= min && (typeof max === 'undefined' || len <= max);
    
  • test/validators/isLength.test.js+144 0 added
    @@ -0,0 +1,144 @@
    +import test from '../testFunctions';
    +
    +describe('isLength', () => {
    +  it('should return false for a string with length greater than the max', () => {
    +    test({
    +      validator: 'isLength',
    +      args: [{ max: 3 }],
    +      invalid: ['test'],
    +    });
    +  });
    +
    +  it('should return true for a string with length equal to the max', () => {
    +    test({
    +      validator: 'isLength',
    +      args: [{ max: 4 }],
    +      valid: ['test'],
    +    });
    +  });
    +
    +  it('should correctly calculate the length of a string with presentation sequences', () => {
    +    test({
    +      validator: 'isLength',
    +      args: [{ max: 4 }],
    +      valid: ['test\uFE0F'],
    +    });
    +
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 5, max: 5 }],
    +      valid: ['test\uFE0F\uFE0F'],
    +    });
    +
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 5, max: 5 }],
    +      valid: ['\uFE0Ftest'],
    +    });
    +
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 9, max: 9 }],
    +      valid: ['test\uFE0F\uFE0F\uFE0F\uFE0F\uFE0F\uFE0F'],
    +    });
    +  });
    +
    +  it('should validate strings by length (deprecated api)', () => {
    +    test({
    +      validator: 'isLength',
    +      args: [2],
    +      valid: ['abc', 'de', 'abcd'],
    +      invalid: ['', 'a'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [2, 3],
    +      valid: ['abc', 'de'],
    +      invalid: ['', 'a', 'abcd'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [2, 3],
    +      valid: ['干𩸽', '𠮷野家'],
    +      invalid: ['', '𠀋', '千竈通り'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [0, 0],
    +      valid: [''],
    +      invalid: ['a', 'ab'],
    +    });
    +  });
    +
    +  it('should validate strings by length', () => {
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 2 }],
    +      valid: ['abc', 'de', 'abcd'],
    +      invalid: ['', 'a'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 2, max: 3 }],
    +      valid: ['abc', 'de'],
    +      invalid: ['', 'a', 'abcd'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 2, max: 3 }],
    +      valid: ['干𩸽', '𠮷野家'],
    +      invalid: ['', '𠀋', '千竈通り'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ max: 3 }],
    +      valid: ['abc', 'de', 'a', ''],
    +      invalid: ['abcd'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ max: 6, discreteLengths: 5 }],
    +      valid: ['abcd', 'vfd', 'ff', '', 'k'],
    +      invalid: ['abcdefgh', 'hfjdksks'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 2, max: 6, discreteLengths: 5 }],
    +      valid: ['bsa', 'vfvd', 'ff'],
    +      invalid: ['', ' ', 'hfskdunvc'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 1, discreteLengths: 2 }],
    +      valid: [' ', 'hello', 'bsa'],
    +      invalid: [''],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ max: 0 }],
    +      valid: [''],
    +      invalid: ['a', 'ab'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ min: 5, max: 10, discreteLengths: [2, 6, 8, 9] }],
    +      valid: ['helloguy', 'shopping', 'validator', 'length'],
    +      invalid: ['abcde', 'abcdefg'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ discreteLengths: '9' }],
    +      valid: ['a', 'abcd', 'abcdefghijkl'],
    +      invalid: [],
    +    });
    +    test({
    +      validator: 'isLength',
    +      valid: ['a', '', 'asds'],
    +    });
    +    test({
    +      validator: 'isLength',
    +      args: [{ max: 8 }],
    +      valid: ['👩🦰👩👩👦👦🏳️🌈', '⏩︎⏩︎⏪︎⏪︎⏭︎⏭︎⏮︎⏮︎'],
    +    });
    +  });
    +});
    
  • test/validators.test.js+0 97 modified
    @@ -5591,32 +5591,6 @@ describe('Validators', () => {
         });
       });
     
    -  it('should validate strings by length (deprecated api)', () => {
    -    test({
    -      validator: 'isLength',
    -      args: [2],
    -      valid: ['abc', 'de', 'abcd'],
    -      invalid: ['', 'a'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [2, 3],
    -      valid: ['abc', 'de'],
    -      invalid: ['', 'a', 'abcd'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [2, 3],
    -      valid: ['干𩸽', '𠮷野家'],
    -      invalid: ['', '𠀋', '千竈通り'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [0, 0],
    -      valid: [''],
    -      invalid: ['a', 'ab'],
    -    });
    -  });
     
       it('should validate isLocale codes', () => {
         test({
    @@ -5695,77 +5669,6 @@ describe('Validators', () => {
         });
       });
     
    -  it('should validate strings by length', () => {
    -    test({
    -      validator: 'isLength',
    -      args: [{ min: 2 }],
    -      valid: ['abc', 'de', 'abcd'],
    -      invalid: ['', 'a'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ min: 2, max: 3 }],
    -      valid: ['abc', 'de'],
    -      invalid: ['', 'a', 'abcd'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ min: 2, max: 3 }],
    -      valid: ['干𩸽', '𠮷野家'],
    -      invalid: ['', '𠀋', '千竈通り'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ max: 3 }],
    -      valid: ['abc', 'de', 'a', ''],
    -      invalid: ['abcd'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ max: 6, discreteLengths: 5 }],
    -      valid: ['abcd', 'vfd', 'ff', '', 'k'],
    -      invalid: ['abcdefgh', 'hfjdksks'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ min: 2, max: 6, discreteLengths: 5 }],
    -      valid: ['bsa', 'vfvd', 'ff'],
    -      invalid: ['', ' ', 'hfskdunvc'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ min: 1, discreteLengths: 2 }],
    -      valid: [' ', 'hello', 'bsa'],
    -      invalid: [''],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ max: 0 }],
    -      valid: [''],
    -      invalid: ['a', 'ab'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ min: 5, max: 10, discreteLengths: [2, 6, 8, 9] }],
    -      valid: ['helloguy', 'shopping', 'validator', 'length'],
    -      invalid: ['abcde', 'abcdefg'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ discreteLengths: '9' }],
    -      valid: ['a', 'abcd', 'abcdefghijkl'],
    -      invalid: [],
    -    });
    -    test({
    -      validator: 'isLength',
    -      valid: ['a', '', 'asds'],
    -    });
    -    test({
    -      validator: 'isLength',
    -      args: [{ max: 8 }],
    -      valid: ['👩🦰👩👩👦👦🏳️🌈', '⏩︎⏩︎⏪︎⏪︎⏭︎⏭︎⏮︎⏮︎'],
    -    });
    -  });
     
       it('should validate strings by byte length', () => {
         test({
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.