← All reports

Enable the offscreen web extension API

Component: WebKit WebExtensions | 3708229

Source/WTF/wtf/PlatformEnableCocoa.h

#if !defined(ENABLE_WK_WEB_EXTENSIONS_OFFSCREEN)
-#define ENABLE_WK_WEB_EXTENSIONS_OFFSCREEN 0 && ENABLE_WK_WEB_EXTENSIONS
+#define ENABLE_WK_WEB_EXTENSIONS_OFFSCREEN ENABLE_WK_WEB_EXTENSIONS
#endif

Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml

WebExtensionOffscreenEnabled:
type: bool
- status: testable
+ status: stable
defaultValue:
WebKitLegacy:
- default: false
+ default: true
WebKit:
- default: false
+ default: true
WebCore:
- default: false
+ default: true

Offscreen API를 사용하면 WebExtension이 눈에 보이는 창 없이 숨겨진 document context를 생성할 수 있습니다. parsing이나 media, clipboard처럼 DOM에 의존하는 로직을 여기서 실행하게 되며, Chrome의 Offscreen Documents API에 대응하는 기능입니다. 이전까지 ENABLE_WK_WEB_EXTENSIONS_OFFSCREEN0 && ENABLE_WK_WEB_EXTENSIONS로 정의되어 있었습니다. runtime preference가 어떻든 기능 자체가 컴파일 단계에서 완전히 제외되었다는 의미입니다. preference의 기본값 또한 off였습니다.

이번 commit은 두 gate를 한꺼번에 제거했습니다. 그 결과 WebExtensions가 지원되는 환경이라면 offscreen document 관련 code path가 빌드에 포함되고, 별도 설정 없이 기본 활성화된 상태가 되었습니다. 여기에 더해 windowScene 조회 부분의 C-style cast가 dynamic_objc_cast로 변경되었는데, ios-safer-cpp bot이 지적한 safer-CPP 정리 작업입니다:

Before:
  ENABLE_WK_WEB_EXTENSIONS_OFFSCREEN = 0 && ENABLE(WK_WEB_EXTENSIONS)  → always compiled OUT
  WebExtensionOffscreenEnabled default = false                        → runtime OFF

After:
  ENABLE_WK_WEB_EXTENSIONS_OFFSCREEN = ENABLE(WK_WEB_EXTENSIONS)      → compiled IN when extensions enabled
  WebExtensionOffscreenEnabled default = true                         → runtime ON by default

빌드에서 아예 제외되어 있던 extension API surface가 이제 설치된 WebExtension이라면 어디서든 기본으로 도달 가능해집니다. 신뢰할 수 없는 extension 코드가 WebKit 내부에서 유발할 수 있는 동작의 범위가 그만큼 넓어졌습니다.

이 code path는 지금까지 shipping build에서 통째로 빠져 있었습니다. 주요 WebExtension API에 비해 fuzzing도, 실제 사용을 통한 노출도 훨씬 적었다는 뜻입니다. 좁게 보면, extension permission 로직과 offscreen document의 lifecycle 관리, 그리고 WebExtensionContextAPIOffscreenCocoa.mm에서 extension context와 offscreen WebPage 사이를 잇는 IPC 경계가 모두 살아있는 attack surface입니다. 출발점으로는 offscreen document가 extension teardown 시점을 기준으로 어떻게 생성되고 정리되는지를 먼저 살펴볼 만합니다. document가 자신을 소유한 context보다 오래 살아남는 상황이야말로 이런 형태의 기능에서 가장 먼저 나타나는 lifetime 버그이기 때문입니다. 넓게 보면, compile-time gate와 runtime preference가 같은 commit에서 동시에 뒤집힌 기능 자체가 재사용 가능한 hunting 패턴입니다. PlatformEnable*.h에서 0 && 형태로 short-circuit된 다른 항목을 검색한 뒤, UnifiedWebPreferences.yaml에서 아직 testable로 표시된 항목과 교차 확인해 볼 필요가 있습니다. 각각이 shipped build를 대상으로 하는 fuzzer가 한 번도 도달하지 못한 코드에 해당하기 때문입니다. 그중 하나가 뒤집히는 시점에는, 이번 경우와 마찬가지로 해당 기능의 IPC message handler에 대한 first-exposure 점검이 필요합니다.