[6] [WebCore] Fix UAF in Range::createContextualFragment via Trusted Types policy callback
Severity: High | Component: WebCore DOM Range | 1e11f2a
Range::createContextualFragment의 Trusted Types createHTML callback 구간에 걸쳐 raw Node*/Element* 캡처가 Ref/RefPtr로 승격되었기 때문에 High로 분류됩니다. 승격이 없는 상태에서는 attacker가 policy callback 내의 JS를 통해 모든 reference를 해제하고 GC를 강제할 수 있었습니다. callback이 반환된 이후 해당 pointer를 역참조하면 이미 해제된 메모리를 대상으로 동작하게 됩니다.
Range::createContextualFragment에서 캡처된 Node/Element reference가 Ref/RefPtr로 변환되어, Trusted Types policy 호출 구간 전반에 걸쳐 lifetime이 고정됩니다.
Source/WebCore/dom/Range.cpp
Re-entrancy UAF: Trusted Types policy callback 호출 전 raw Node pointer를 캡처하고, attacker JavaScript 동기 실행 이후 해당 pointer를 역참조하는 패턴.
Patch Details
context node와 start container에 대한 함수의 로컬 캡처가 reference-counted 형태로 변경되었습니다. policy callback 자체에는 수정이 없습니다.
Background
Range::createContextualFragment는 Range의 start container 컨텍스트 안에서 HTML fragment를 파싱합니다. Trusted Types의 createHTML policy는 입력 문자열 경로상에 위치하며, 파싱 전에 사용자가 등록한 JavaScript callback을 실행하여 제공된 HTML을 sanitize합니다.
Analysis
패치 이전에는 함수가 Range의 boundary에서 raw Node*/Element*를 추출한 뒤, createHTML 호출을 거치는 동안에도 그대로 사용하는 구조였습니다. 이 callback은 attacker가 제어하는 JS입니다. callback 내에서 Range를 변경할 수 있습니다. 예를 들어 range.setEnd(document, 0)을 호출하면, 구현상 순서가 역전될 때 setEnd가 start를 end 위치로 이동시킵니다. 이 밖에도 살아있는 모든 reference를 해제하고 GC를 강제하는 것도 가능합니다.