← All issues

[14] [WebKit] Add MessagePort entanglement check to takeAllMessagesForPort IPC

Severity: High | Component: WebKit Network process | da44cdb

패치에 MESSAGE_CHECK_COMPLETION이 추가되어, m_processEntangledPorts에 속하지 않는 port를 지정한 TakeAllMessagesForPort IPC를 거부합니다. 패치 이전에는 port identifier를 알고 있는 WebContent process라면 어떤 process든, 다른 process 소유의 port에 대기 중인 message를 수집할 수 있었습니다. Severity를 High로 평가한 근거입니다.

NetworkConnectionToWebProcess::takeAllMessagesForPort는 전달받은 MessagePortIdentifierm_processEntangledPorts와 대조한 뒤, 일치하지 않으면 송신자를 kill하는 경로로 처리합니다.

Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp

+ MESSAGE_CHECK_COMPLETION(m_processEntangledPorts.contains(identifier), completionHandler({ }, false));
m_networkProcess->messagePortChannelRegistry().takeAllMessagesForPort(identifier, WTFMove(completionHandler));

IPC 인증 우회: 침해된 renderer가 위조된 identifier를 이용해 cross-process MessagePort의 대기 message를 수집한 버그.

IPC entry point가 global registry를 조회하기 전에 port 소유권을 먼저 검증하도록 변경되었습니다. 거부된 경우 completion handler는 empty/false를 반환합니다.

Network process는 cross-process MessagePort 전달을 담당하는 신뢰된 중개자입니다. port가 WebContent process 간에 전달될 때(예: SharedWorker handoff를 통해), pending message는 수신 측이 TakeAllMessagesForPort를 통해 drain할 때까지 Network process에서 대기하게 됩니다. m_processEntangledPorts는 해당 connection이 정당하게 소유한 port를 추적합니다.

패치 이전, Network process는 어떤 MessagePortIdentifier든 수락한 뒤 global registry에 전달했습니다. MessagePortIdentifierProcessIdentifierPortIdentifier의 쌍이며, 둘 다 uint64_t 타입입니다. 침해되거나 적대적인 WebContent process가 identifier를 획득하거나 추측할 수 있다면, 해당 IPC를 발행해 queue를 수집하는 것이 가능했습니다.

regression test는 IPC_TESTING_API를 사용해 다음과 같이 동작을 검증합니다:

WebView A   create channel             →  CreateNewMessagePortChannel  →  intercept arg buffer, read port id
WebView A   post 3 messages
WebView C   forge TakeAllMessagesForPort(port id)
           pre-fix: returns 3 messages  ← cross-process IPC harvest
           post-fix: returns 0          ← MESSAGE_CHECK_COMPLETION rejects

이 취약점의 primitive는 MessagePort message 내용에 한정된 cross-process information disclosure입니다. memory corruption이 아닌, IPC trust boundary에서의 logic bug에 해당합니다.

이 버그는 cross-process port queue에 대한 process별 소유권 불변성을 약화시킵니다.