← All issues

[1] [WebKit] Remove SetCORSDisablingPatterns IPC from NetworkConnectionToWebProcess

UI process took the renderer's word on which origin owned a lock — until someone asked what `committedOrigins` actually contained.

Severity: High | Component: WebKit NetworkProcess | 841ad59

이 diff는 WebContent에서 도달 가능한 IPC를 제거합니다. 해당 IPC는 m_pageCORSDisablingPatterns/originAccessPatterns에 임의의 URL 패턴을 직접 기록할 수 있었고, renderer 페이지의 outbound cross-origin 요청에 대한 same-origin 적용을 무력화했습니다. 손상된 WebProcess에서 추가 권한 상승 없이 직접 도달 가능한 primitive이기 때문에 High로 평가됩니다.

NetworkConnectionToWebProcess에서 SetCORSDisablingPatterns(PageIdentifier, Vector<String>) IPC가 제거되었습니다. 정책 전달 경로는 WebPageProxyNetworkProcess 직접 경로로 재구성되었습니다. 패치 이전에는 NetworkProcess가 각 패턴을 UserContentURLPattern으로 파싱했습니다. 이를 PageIdentifier를 키로 저장하고, shouldDisableCORSForRequestTo()가 참조하는 per-connection NetworkOriginAccessPatterns에 추가했습니다.

Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp

-void NetworkConnectionToWebProcess::setCORSDisablingPatterns(PageIdentifier pageIdentifier, Vector<String>&& patterns)
-{
- Vector<UserContentURLPattern> parsedPatterns;
- parsedPatterns.reserveInitialCapacity(patterns.size());
- for (auto&& pattern : WTFMove(patterns)) {
- UserContentURLPattern parsedPattern(WTFMove(pattern));
- if (parsedPattern.isValid()) {
- originAccessPatterns().allowAccessTo(parsedPattern);
- parsedPatterns.append(WTFMove(parsedPattern));
- }
- }
- parsedPatterns.shrinkToFit();
- m_networkProcess->setCORSDisablingPatterns(pageIdentifier, WTFMove(parsedPatterns));
-}

Confused-deputy IPC: NetworkProcess가 per-page CORS 비활성화 정책의 신뢰 출처를 WebContent로 처리했습니다. 실제 정책은 UIProcess SPI에서 시작됩니다.

Renderer에서 시작되는 경로가 삭제되었습니다. WebPage::synchronizeCORSDisablingPatternsWithNetworkProcess는 제거되었고, APIPageConfiguration::setCORSDisablingPatterns는 이제 패턴을 WebPageProxy에 저장합니다. 이후 UI→Network IPC 채널을 통해 파싱된 패턴이 NetworkProcess로 전달됩니다. m_pageCORSDisablingPatterns 맵과 shouldDisableCORSForRequestTo() 조회 로직은 유지되며, 변경된 것은 해당 값을 기록하는 주체뿐입니다.

WebKit의 CORS 구현은 WebContent(preflight, 응답 검사)와 NetworkProcess(cross-origin 스케줄링) 양쪽에 걸쳐 있습니다. shouldDisableCORSForRequestTo()는 per-page allow list인 m_pageCORSDisablingPatterns와 per-connection NetworkOriginAccessPatterns를 참조하여, 매칭되는 URL의 CORS 처리를 건너뜁니다. 이 정책의 합법적인 기록 주체는 embedder에 한하며, -[WKWebView _setCORSDisablingPatterns:]를 통해 UIProcess 내 APIPageConfiguration으로 전파됩니다. UI/Network(신뢰)와 WebContent(비신뢰) 사이의 IPC sandbox 경계상, CORS를 완화하는 정책은 renderer를 거쳐서는 안 됩니다.

패치 이전의 경로는 UIProcess → WebContent → NetworkProcess 순서였습니다. WebContent process가 패턴을 보관하고 NetworkProcess에 동기화하는 구조였습니다. 손상된 WebContent process는 기존 NetworkConnectionToWebProcess endpoint를 통해 SetCORSDisablingPatterns(pageIdentifier, ["*://*/*"]) 메시지를 조작하여 전송할 수 있었습니다. NetworkProcess는 호출자의 권한을 검증하지 않은 채 각 UserContentURLPattern을 파싱하고 originAccessPatterns()에 추가했습니다. 이후 해당 페이지의 모든 outbound 요청은 shouldDisableCORSForRequestTo()에서 매칭되어 CORS를 건너뛰었으며, 네트워크 측 same-origin preflight와 credentials 처리도 예외가 아니었습니다.

이 primitive는 직접적입니다. 손상된 renderer는 page identifier 범위 내에서, NetworkProcess가 도달 가능한 임의의 HTTP origin에 대해 cross-origin read primitive를 획득합니다. SOP와 CORS는 웹 플랫폼 격리의 핵심 불변성으로, 이 IPC는 호출 페이지에 대해 해당 불변성을 무력화했습니다. fix는 renderer를 기록 주체에서 완전히 제거하고, 패턴이 WebPageProxy → NetworkProcess로 직접 전달되도록 신뢰 경로를 복원했습니다.

이 취약점은 cross-origin 정책 영역에서 WebContent ↔ NetworkProcess 신뢰 경계를 약화시킵니다. 해당 primitive는 임의의 HTTP origin에 대해 exploit 수준의 영향력을 가집니다. 구체적으로는 페이지의 network namespace에서 도달 가능한 cross-origin endpoint로부터 cookie, 응답 본문, 헤더를 읽을 수 있습니다.