| 항목 | 내용 |
|---|---|
| CVE ID | CVE-2026-15718 |
| 영향 제품 | Mozilla Firefox 152.0.6 미만 |
| 영향 컴포넌트 | JavaScript: WebAssembly (SpiderMonkey) |
| 심각도 | Mozilla Critical |
| 공개일 | 2026-07-14 |
| 수정 버전 | Firefox 152.0.6 |
| CVSS v3.1 | CISA-ADP 5.4 Medium — AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N |
| CWE | CWE-763: Release of Invalid Pointer or Reference |
| 공개 악용 상태 | Mozilla는 public exploit code를 인지하지만, 실제 악용 사례는 인지하지 못했다고 밝힘 |
| 분석 기준 | Mozilla MFSA·NVD·공개 SpiderMonkey 소스/문서. 보안 Bugzilla와 수정 diff는 접근 제한 상태 |
CVE-2026-15718은 Firefox의 JavaScript: WebAssembly 컴포넌트에 있는 invalid pointer 취약점이다. Mozilla는 이를 Critical로 분류하고 Firefox 152.0.6에서 수정했다. 또한 public exploit code가 있음을 인지하지만, 권고 발표 시점에 실제 공격에 쓰인 사례는 알지 못한다고 밝혔다. NVD는 Firefox 152.0.6 미만을 영향 범위로 기록하며, CISA-ADP는 CWE-763으로 매핑했다.
이 사례가 보여 주는 핵심은 WebAssembly가 안전한 바이트코드 형식이라도, 이를 실행하는 브라우저 엔진은 결국 네이티브 메모리와 포인터를 관리한다는 점이다. SpiderMonkey는 WebAssembly 모듈을 검증·컴파일하고, 인스턴스·메모리·테이블·JIT 코드의 수명을 연결한다. 이 연결에서 이미 해제됐거나 다른 객체에 속한 주소를 유효하다고 취급하면, 웹 페이지가 제공한 입력이 엔진 내부의 메모리 안전성 경계를 흔들 수 있다. 단, 공개된 보안 자료에는 문제가 된 포인터의 종류·취약 함수·정확한 trigger가 없으므로, 이 보고서는 일반적인 구현 모델을 실제 CVE의 확정 원인으로 단정하지 않는다.
WebAssembly(Wasm)는 웹 페이지가 이진 모듈을 전달하면 브라우저가 이를 검증하고 실행하는 형식이다.
JavaScript에서 WebAssembly.Module과 WebAssembly.Instance를 만들 수 있으며, 모듈은 코드와
선언을, 인스턴스는 imports·globals·memory·table 같은 실행별 상태를 가진다. 따라서 같은 모듈을
여러 번 인스턴스화하면 코드는 공유될 수 있어도 각 인스턴스의 실행 상태는 달라질 수 있다.
Firefox의 SpiderMonkey는 JavaScript와 WebAssembly 구현 라이브러리이며, 공개 문서는 Wasm 입력을 빠르게 기계어로 옮기는 baseline 컴파일러와 중간 표현(MIR)을 거쳐 최적화하는 Ion 컴파일러를 설명한다. 즉 페이지가 제공한 Wasm 바이트는 단순히 해석되는 데서 끝나지 않고, 엔진의 네이티브 코드·레지스터·힙 객체와 연결된다.
웹 페이지가 제공한 Wasm bytes
│
▼
parse / validate / compile
│
▼
Module (공유 가능한 코드·메타데이터)
│ instantiate(imports)
▼
Instance ───┬── Memory (linear memory)
├── Table / globals
└── JIT machine code에서 참조하는 실행 상태
Wasm의 형식 검증은 모듈 안의 타입·제어 흐름·명령을 검사한다. 하지만 검증된 Wasm이라는 사실만으로 엔진 구현의 포인터 관리까지 자동으로 안전해지지는 않는다. 검증기는 Wasm 프로그램의 규칙을 확인하고, C++로 구현된 엔진은 별도로 객체 수명, 경계 검사, 가비지 수집(GC) 참조, JIT 코드와 데이터의 연결을 정확히 지켜야 한다.
공개 SpiderMonkey 소스의 wasm::Module은 module metadata와 compilation artifact를 보관하고,
인스턴스화 과정에서 functions, memories, tags, tables를 각각 생성하는 함수를 둔다. 이 구조는
모듈의 컴파일 산출물과 실행 중인 인스턴스 객체가 서로 다른 소유자·수명·정리 시점을 가질 수 있음을
보여 준다.
Module M
code / metadata
├──────── instantiate ────────> Instance A ──> Memory A
│ │
└──────── instantiate ────────> Instance B ──> Memory B
안전한 참조: 실행 중인 코드가 현재 Instance의 유효한 상태만 가리킴
위험한 참조: A가 종료·교체된 뒤에도 A의 주소를 B 또는 JIT 경로에서 사용
여기서 포인터는 단순한 숫자가 아니다. 어느 객체의 어느 필드를 가리키는지, 그 객체가 아직 살아 있는지, 객체 이동·재할당·해제 뒤에도 같은 의미인지가 함께 보장돼야 한다. 특히 최적화된 네이티브 코드는 실행 속도를 위해 instance data나 memory base 같은 주소를 빠르게 쓰려 한다. 주소를 캐시하거나 전달하는 경로는 수명 전환과 동기화돼야 한다.
Wasm의 Memory는 프로그램이 offset으로 접근하는 선형 바이트 배열이다. 정상적인 Wasm load/store는
현재 memory의 길이를 넘지 않도록 검사돼야 한다. 이것은 Wasm 프로그램이 자기 linear memory 밖을
읽고 쓰지 못하게 하는 규칙이다.
Wasm 프로그램 관점
offset + access_size < memory_length ──> 허용
그 밖의 접근 ──> trap
엔진 구현 관점
Memory object ──> native buffer / base pointer / length
▲
└─ 이 참조 자체가 현재 유효한 객체인가?
두 번째 질문은 첫 번째 경계 검사와 다르다. length가 맞아도 엔진이 이미 무효화된 Memory나
Instance의 base pointer를 사용하면 위험하다. 반대로 객체가 살아 있어도 이전 인스턴스의
메모리를 현재 인스턴스의 메모리로 착각하면 격리와 정확성이 깨진다. 이런 문제는 use-after-free,
stale pointer, 잘못된 소유권 이전, 해제 함수에 잘못된 주소를 넘기는 오류 등 여러 형태가 될 수
있다.
SpiderMonkey는 Wasm을 기계어로 컴파일할 수 있다. JIT 코드가 C++ 객체나 GC 관리 객체를 참조할 때는
GC가 그 객체를 살아 있는 것으로 인식하게 하거나, 호출 사이에 포인터가 더 이상 유효하지 않음을
전제로 다시 읽어야 한다. 공개 Debugger 문서는 Debugger.Script의 Wasm 모듈 참조가 모듈의 GC를
막는 strong reference라고 설명한다. 이는 객체 수명이 기능과 보안 양쪽에서 명시적으로 관리돼야
함을 보여 준다.
안전한 수명 경계
JIT/engine state ── strong root 또는 유효성 보장 ──> Wasm object
│
└─ 객체 폐기 전: 모든 사용자 중지·참조 제거·재검증
위험한 수명 경계
object free / replace ──> 이전 native pointer가 JIT/helper에 남음 ──> 역참조 또는 해제
실제 엔진에는 write barrier, rooting, 핸들 타입, epoch/상태 검사 같은 다양한 방어가 있을 수 있다. CVE-2026-15718이 이 중 어느 계층을 우회했는지는 공개된 자료만으로 알 수 없다.
- Mozilla MFSA 2026-67은 이 취약점을 JavaScript: WebAssembly component의 invalid pointer로 분류하고 Critical impact를 부여했다.
- Firefox 152.0.6이 수정 버전이며, Mozilla 릴리스 노트는 이 버전을 2026-07-14 Release 채널에 제공했다고 기록한다.
- Mozilla는 public exploit code의 존재를 인지하지만 in-the-wild 악용 사례는 인지하지 못한다고 밝혔다.
- NVD는 Firefox 152.0.6 미만을 영향 범위로, CISA-ADP의 CVSS를
AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N, CWE를 CWE-763으로 기록한다. - 연결된 Bugzilla bug 2045443은 권한 제한으로 세부 설명과 patch diff를 읽을 수 없었다.
공개 자료는 "invalid pointer"까지만 확인해 준다. 따라서 다음은 Wasm 엔진에서 반드시 지켜야 할 불변식과, 그 불변식이 깨질 때의 일반 모델이다. CVE-2026-15718의 실제 객체·API·해제 순서나 exploit 절차가 아니다.
패치 전 가능한 메모리 안전성 경계 실패 모델 (추정)
공격자 제어 Wasm 모듈 / JS 호출
│ instantiate · call · state transition
▼
SpiderMonkey Wasm object / helper / JIT 경로
│
├─ 정상: 현재 소유자 + 유효 수명 + 경계 검증
│
└─ 실패 가능성: 해제됨·교체됨·다른 객체 소유인
native pointer를 유효하다고 사용하거나 해제
│
▼
메모리 안전성 위반
│
▼
process 내 충돌·정보 노출·코드 실행 가능성
(정확한 영향은 공개 자료로 미확정)
핵심 불변식은 다음과 같이 표현할 수 있다.
pointer P를 읽거나 해제하기 직전:
P != null
P의 소유자와 현재 실행 상태가 일치
P가 가리키는 객체/할당은 아직 살아 있음
P의 타입·크기·수명 규칙이 현재 연산과 일치
어느 하나라도 깨지면 C++ 수준에서 정의되지 않은 동작이 시작될 수 있다. 예를 들어 이미 해제된 공간을 읽으면 stale data를 보거나 충돌할 수 있고, 재사용된 공간에 쓰면 전혀 다른 객체를 손상시킬 수 있다. 잘못된 주소를 해제하면 allocator 메타데이터 손상 또는 즉시 종료로 이어질 수 있다. Wasm의 입력 형식이 바이트 단위로 복잡하고, JavaScript·GC·JIT·비동기 컴파일이 만나는 만큼, 구현은 빠른 경로에서도 포인터 수명 불변식을 잃지 않아야 한다.
Mozilla가 Critical로 분류한 사실은 위험도를 보여 주지만, 그것만으로 sandbox escape, 임의 코드 실행, 다른 origin 데이터 접근을 확정할 수는 없다. NVD의 현재 CISA-ADP 평가는 부분적 기밀성 영향과 무결성 영향 없음으로 기록돼 있으며, 이는 공개된 exploit code의 구체적 능력을 검증한 설명이 아니다. 정확한 보안 결과는 보안 bug나 수정 코드가 공개될 때까지 미확정으로 남겨야 한다.
웹 페이지의 JavaScript와 Wasm은 보통 sandboxed content process에서 실행된다. 이 sandbox는 OS와 브라우저 핵심 기능을 보호하는 중요한 방어선이지만, content process의 메모리 안전성이 필요 없다는 뜻은 아니다. 공격자는 먼저 content process에서 실행 가능한 강력한 원시 동작을 얻으려 할 수 있고, 그 뒤에 별도의 sandbox 탈출이나 브라우저 경계 우회와 조합하려 할 수 있다.
웹 콘텐츠
│
▼
SpiderMonkey/Wasm memory safety ──> content process 권한 안의 영향
│ │
└─ 별도 취약점이 있을 때만 ─────────────┘
sandbox / browser 경계로 확장 가능
이 연결은 일반적인 브라우저 위협 모델의 설명이다. CVE-2026-15718이 실제로 다단계 체인을 필요로 했는지 또는 그런 체인에 쓰였는지는 Mozilla가 확인하지 않았다. 그래서 업데이트 판단은 추측된 공격 사슬이 아니라 Critical 등급, 영향 제품, 공개 exploit code 존재라는 확인된 정보에 근거해야 한다.
확인 가능한 조치는 Firefox를 152.0.6 이상으로 업데이트하는 것이다. Mozilla MFSA 2026-67과 릴리스 노트는 모두 152.0.6을 수정 버전으로 명시한다. 조직 환경에서는 업데이트 배포 뒤 실제 설치 버전을 확인하고, 자동 업데이트가 지연된 endpoint를 별도로 점검해야 한다.
보안 Bugzilla와 patch diff가 비공개이므로 패치 후의 코드·객체 수명 흐름을 그릴 수 없다. 예컨대
포인터를 nullptr로 초기화했는지, 소유권을 smart pointer/GC root로 바꿨는지, JIT의 stale cache를
제거했는지, 해제 순서를 수정했는지는 확인되지 않았다. 이를 일반적인 "검증 추가" 그림으로 바꾸면
실제 수정 메커니즘을 꾸며 내는 것이 된다.
운영상으로는 신뢰할 수 없는 페이지를 열지 않는 방법이 임시 완화일 수 있으나, Mozilla가 공개 exploit code의 존재를 알린 상황에서 대체 통제가 될 수 없다. 업데이트가 우선이며, 이후 공개되는 patch와 regression test에서 다음을 재검증해야 한다.
- 문제가 된 포인터의 실제 타입과 소유자(
Module,Instance,Memory, JIT 상태 등) - 해제·교체·GC·컴파일 사이에서 깨진 수명 불변식
- 패치가 추가한 lifetime check 또는 ownership 변경과 regression test
- 공개 exploit code의 출처·신뢰성·실제 영향 범위
Mozilla는 public exploit code가 있음을 인지한다고만 공개했다. 이 실행에서는 해당 코드의 위치, 작성자, 내용, 신뢰성을 독립적으로 확인하지 못했고, 어떤 exploit 또는 PoC도 내려받거나 실행하지 않았다. 따라서 본문은 exploit 구현을 근거로 삼지 않으며 재현 단계도 제공하지 않는다.
- Bugzilla bug 2045443이 접근 제한 상태여서 실제 취약 함수, 포인터 종류, trigger, patch diff, regression test를 확인하지 못했다.
- CWE-763은 invalid pointer/reference의 한 분류일 뿐이다. 이 CVE가 use-after-free, double free, stale JIT pointer, 잘못된 ownership 중 어디에 해당하는지는 공개되지 않았다.
- Mozilla의 Critical 등급과 NVD의 현재 CISA-ADP CVSS는 서로 다른 공개 평가 축이다. 정확한 exploit primitive와 최종 영향은 세부 자료가 나올 때까지 확정할 수 없다.
- public exploit code의 출처와 신뢰성은 독립적으로 검증하지 못했다.
- Mozilla, MFSA 2026-67: Security Vulnerabilities fixed in Firefox 152.0.6
- Mozilla, Firefox 152.0.6 Release Notes
- NVD, CVE-2026-15718 Detail
- Firefox Source Docs, SpiderMonkey
- Mozilla Searchfox, SpiderMonkey
js/src/wasmsource directory - Mozilla Searchfox,
wasm::Moduleand instantiation declarations - Firefox Source Docs, Debugger.Script for WebAssembly
- Mozilla Bugzilla, Bug 2045443 (접근 제한 상태 확인)