← All issues

Web Extension Error Reporting with URL Masking Bypass

dde2f84

Source/WebCore/bindings/js/WebCoreJSClientData.cpp

+String unmaskedSourceURLFromException(const JSC::Exception& exception, JSC::VM& vm)
+{
+ for (auto& frame : exception.stack()) {
+ String url = frame.sourceURL(vm, JSC::AllowURLOverride::No);
+ if (!url.isEmpty() && url != "[native code]"_s)
+ return url;
+ }
+ return emptyString();
+}

Source/WebCore/bindings/js/JSDOMExceptionHandling.cpp

+ if (globalObject->hasScriptErrorCallbacks()) {
+ auto unmaskedSourceURL = exceptionSourceURL;
+ if (auto url = unmaskedSourceURLFromException(*exception, vm); !url.isEmpty())
+ unmaskedSourceURL = url;
+ globalObject->invokeScriptErrorCallbacks(errorMessage, unmaskedSourceURL, lineNumber, columnNumber);
+ }

이 commit은 Web Extension에서 발생하는 미처리 exception과 unhandled promise rejection을 보고하는 기능을 추가합니다. 오류는 새로운 WebProcess→UIProcess IPC 메시지를 통해 extension context로 전달됩니다. 또한 JSC의 StackFrame::sourceURL()AllowURLOverride 옵션이 도입되었습니다. 이를 통해 내부 오류 보고 목적으로 실제 extension 스크립트 URL을 수집할 때 webkit-masked-url://hidden/ 마스킹을 우회할 수 있습니다.

main world에 주입된 content script는 일반적으로 webkit-masked-url://hidden/을 외부에 노출되는 source URL로 사용합니다. host 페이지가 설치된 extension을 fingerprinting하지 못하도록 막기 위한 보호 장치입니다. 다만 오류 보고 기능에서는 진단 목적으로 실제 URL이 필요합니다.

Content Script (main world)
  source URL visible to page:  webkit-masked-url://hidden/
  real URL (internal):         extension-url://abc/cs.js
         │
         └─ throws exception
                  │
                  ▼
         reportException()
           ├─ exceptionSourceURL (masked) ──► page onerror / console
           └─ hasScriptErrorCallbacks()?
                └─ Yes:
                     unmaskedSourceURLFromException()
                       │  StackFrame::sourceURL(AllowURLOverride::No)
                       ▼
                     real URL extracted → IPC → UIProcess

AllowURLOverride::No 경로는 URL 마스킹 메커니즘을 의도적으로 우회하는 설계입니다. 이 경로가 extension 오류 보고 이외의 맥락에서 접근 가능하다면, content script fingerprinting 보호가 무력화될 가능성이 있습니다.

hasScriptErrorCallbacks()가 마스킹 해제된 URL 추출을 제어합니다. extension이 아닌 global object(일반 페이지 window, worker)에 script error callback이 등록될 수 있다면 — type confusion이나 예상치 못한 호출 경로를 통해서 — extension content script의 실제 URL이 의도하지 않은 수신자에게 전달될 가능성이 있습니다. 새로 추가된 IPC 메시지 didEncounterScriptError는 WebProcess→UIProcess 경계를 넘어 source URL을 전달하는 만큼, UIProcess 측에서는 보고된 URL이 실제로 해당 extension에 속하는지 검증해야 합니다.