피드로 돌아가기
Dev.toSecurity
원문 읽기
JavaScript JIT 엔진을 CFI, PAC, 메모리 태깅, 타겟 퍼징으로 다층 강화해 타입 혼동과 use-after-free 익스플로잇 체인을 차단
Hardening JavaScript JITs: Practical Mitigations for Modern Engines
AI 요약
Context
JavaScript JIT 컴파일러는 신뢰할 수 없는 입력을 최적화된 네이티브 코드로 변환하며, 타입 혼동과 use-after-free 같은 취약점이 정보 누수→메모리 프리미티브→코드 포인터 손상→샌드박스 탈출로 이어지는 익스플로잇 체인을 형성한다. V8 고심도 크래시의 반복적인 발생이 이러한 공격 경로를 실증한다.
Technical Solution
- Control-Flow Integrity (CFI) 적용: Clang의
-fsanitize=cfi플래그로 간접 호출과 가상 디스패치를 유효한 대상으로만 제한하며, Dromaeo 벤치마크에서 1% 미만의 오버헤드만 추가 - Hardware 메모리 보호 키 도입: Memory Protection Keys (x86 PKU)와 per-thread/pkey 샌드박싱으로 JIT 코드 페이지를 쓰기 불가능 상태로 유지하고, 코드 생성 중에만 일시적으로 쓰기 가능 영역 활성화
- Pointer Authentication (PAC) 배포: ARMv8.3+ 플랫폼에서 포인터 서명으로 ROP 및 리턴 타겟 손상을 방지하되, PACMAN 마이크로아키텍처 공격을 고려해 단독 방어보다는 다층 완화의 한 계층으로 활용
- Arm Memory Tagging Extension (MTE) 운영: SYNC/ASYNC 모드로 힙 메모리 에러를 탐지하고, 특히 Android NDK 플랫폼에서 use-after-free 검증
- 타겟 퍼징 자동화: Fuzzilli와 ClusterFuzz/JS-Fuzzer로 V8, SpiderMonkey, JSC에 대한 체계적 퍼징 실행하고, GWP-ASan 샘플링으로 프로덕션 환경에서 힙 버그를 무시할 수 있는 오버헤드로 탐지
Impact
Clang CFI 측정 오버헤드 1% 미만 (Dromaeo 벤치마크), GWP-ASan 프로덕션 배포 시 무시할 수 있는 오버헤드
Key Takeaway
JIT 익스플로잇 체인을 차단하려면 정보 누수→메모리 프리미티브→코드 포인터 손상→샌드박스 탈출 중 하나 이상의 단계를 저비용으로 끊어야 하며, CFI + 하드웨어 포인터 보호 + 경량 메모리 검사를 층별로 조합하면 공격자의 비용을 지수적으로 증가시킨다.
실천 포인트
JavaScript 엔진을 운영하는 브라우저/런타임 팀에서 퍼저와 GWP-ASan 보고를 먼저 수정한 후 CFI와 플랫폼별 포인터 보호(PAC on ARM, pkey on x86)를 순차적으로 계층화하면, 타입 혼동 및 use-after-free 익스플로잇의 성공 필요 단계를 3~5단계 이상으로 증가시킬 수 있다.