[2] WebPasteboardProxy missing frame-ancestry check under Site Isolation
Under Site Isolation, a copy operation that named someone else's frame could pull a cross-site iframe's DOM straight onto the pasteboard.
diff가 공격자 제공 frame identifier에 대한 subtree 소속 검증을 추가한다는 점에서 High로 평가됩니다. 패치 이전에는 손상된 WebContent process가 pasteboard IPC에 임의의 frame identifier를 지정할 수 있었고, 관련 없는 cross-site frame의 직렬화된 DOM이 수집되는 경로가 존재했습니다. 단, sandbox escape은 포함되지 않으며, 영향 범위는 대상 FrameIdentifier를 특정하고 pasteboard를 다시 읽어오는 조건 하의 cross-site 정보 유출에 한정됩니다.
WebPasteboardProxy는 수신한 remote frame ID에 대해 subtree 검증을 전혀 수행하지 않았습니다. 이로 인해 관련 없는 cross-site remote frame의 콘텐츠가 pasteboard에 기록될 수 있었습니다. 이번 수정에서는 WebPasteboardProxy 내에서 사용되는 모든 remote frame ID가 복사 대상 root frame ID의 하위 frame인지 확인하는 message check가 추가되었습니다.
Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm
LayoutTests/http/tests/ipc/resources/write-web-archive-frame-ancestry-check-iframe.html
Patch Details
새로운 static helper validateFrameIdentifiers(rootFrameIdentifier, localFrameArchives, remoteFrameIdentifiers)는 전달된 각 frame identifier를 순회하며, 복사 대상 root frame의 subtree에 속하는지 확인합니다. isAllowed()는 root frame 자체에 대해서는 true를 반환합니다. 그 외의 frame은 WebFrameProxy::webFrame(identifier)로 조회한 뒤, isInSubtree lambda가 parentFrame()을 따라 root까지 거슬러 올라가 ancestry chain이 rootFrameIdentifier에 도달하는지 검증합니다. 알 수 없는(null) frame 역시 허용 대상으로 처리됩니다. 이 helper는 content.localFrameArchives의 모든 key를 검증하며, 각 archive 자체의 frameIdentifier()와 subframeIdentifiers(), 그리고 모든 remoteFrameIdentifiers 항목도 마찬가지로 확인합니다. writeWebContentToPasteboard에는 MESSAGE_CHECK가, writeWebArchiveToPasteBoard에는 MESSAGE_CHECK_COMPLETION이 추가되었습니다. WriteWebArchiveToPasteBoard의 응답 타입은 기존의 단순한 int64_t changeCount에서 (WriteWebArchiveToPasteBoardResult result, int64_t changeCount) 형태로 확장되었습니다. WriteWebArchiveToPasteBoardResult는 Success / FailureDueToInvalidFrameIdentifiers / FailureOther 값을 갖는 새로운 enum class로, WebProcess와 테스트 코드가 거부 결과를 확인할 수 있게 됩니다.
Site Isolation pasteboard broker의 IPC trust boundary를 넘는 공격자 제공 frame identifier에 대한 frame ancestry(subtree 소속) 검증 누락.
Background
Site Isolation은 cross-site iframe을 별도의 WebContent process에 배치하는 WebKit의 아키텍처입니다. 각 frame은 프로세스 전반에 걸쳐 고유한 FrameIdentifier를 가지며, UI process는 이를 통해 frame을 식별합니다. WebPasteboardProxy는 WebContent process를 대신해 pasteboard 작업을 중개하는 UI-process IPC 메시지 수신자입니다. LegacyWebArchive는 frame과 하위 frame을 직렬화한 WebKit의 표현 형식(.webarchive)이며, createOneWebArchiveFromFrames는 root frame과 local frame archive, 그리고 remote(프로세스 외부) subframe identifier를 조합해 하나의 archive를 생성합니다. WebFrameProxy::webFrame(identifier)는 FrameIdentifier를 해당 frame의 UI-process proxy로 변환하며, parentFrame() 체인이 frame tree 구조를 나타냅니다.
MESSAGE_CHECK와 MESSAGE_CHECK_COMPLETION은 IPC 유효성 검사 매크로입니다. 검증 실패 시 해당 메시지를 유효하지 않은 것으로 처리하고, 발신자를 종료하거나 오류를 반환합니다. 공격자가 제어하는 IPC 입력에 대해 불변 조건을 강제하는 표준 메커니즘입니다. IPCTestingAPI는 레이아웃 테스트에서 원시 IPC 메시지를 직접 합성할 수 있게 해주는 테스트 전용 기능으로, 이번 테스트에서는 비하위 frame을 지정하는 요청을 위조하는 데 사용되었습니다.
Analysis
이 취약점은 IPC handler에서 발생한 인가 누락이자 프로세스 간 capability 검증 부재로, Site Isolation 경계 우회에 해당합니다. 패치 이전에는 writeWebArchiveToPasteBoard와 writeWebContentToPasteboard가 IPC 메시지에서 받은 rootFrameIdentifier, 임의의 local frame archive key, remoteFrameIdentifiers를 그대로 createOneWebArchiveFromFrames에 전달했습니다. 해당 identifier들이 rootFrameIdentifier를 root로 하는 subtree에 속하는지는 전혀 확인하지 않았습니다.
Site Isolation 하에서 cross-site subframe은 서로 다른 WebContent process에 존재하지만, FrameIdentifier는 UI process 전반에서 전역적으로 주소를 지정할 수 있습니다. UI process의 WebPasteboardProxy는 다른 frame의 프로세스에 접근해 직렬화된 DOM을 수집하고 multi-frame web archive를 조합하는 신뢰된 중개자입니다. ancestry 검증이 없는 상황에서는, 자신의 frame을 직렬화하는 WebContent process가 전혀 관련 없는 cross-site remote frame을 "remote subframe"으로 지정할 수 있었습니다. 결과적으로 해당 frame의 콘텐츠가 수집되어 pasteboard에 기록될 수 있었습니다.
regression test는 이 취약점의 유발 방식을 직접 보여줍니다. iframe이 자신의 프로세스 외부에 있는 부모 frame의 FrameIdentifier를 remote subframe으로 지정하는 IPC를 위조했을 때, 패치 이전에는 해당 요청이 수락되었지만 패치 이후에는 FailureDueToInvalidFrameIdentifiers가 반환됩니다. 공격 시나리오를 살펴보면, 공격자는 WebContent process에서 위조한 WriteWebArchiveToPasteBoard를 전송합니다. 이때 rootFrameIdentifier는 자신의 frame으로 설정하고, remoteFrameIdentifiers(또는 local archive의 subframe identifier)에는 관련 없는 cross-site frame을 지정합니다. createOneWebArchiveFromFrames는 해당 비하위 frame의 직렬화된 콘텐츠를 archive에 포함시켜 pasteboard에 기록하며, 공격자 스크립트는 이를 다시 읽어올 수 있습니다. 대상 FrameIdentifier를 알고 있다는 조건 하의 cross-site 콘텐츠 유출 primitive에 해당합니다.
이 취약점은 Site Isolation과 same-origin trust boundary를 약화시킵니다. 보안 모델상 WebContent process는 복사 작업 시 자신의 frame subtree만을 pasteboard에 직렬화할 수 있어야 합니다. 지정된 frame들이 복사를 시작한 frame의 subtree에 속하는지 강제하는 것은 UI-process broker의 역할입니다. 패치 이전에는 이 불변 조건이 강제되지 않아, 악의적인 WebContent process가 다른 origin의 cross-process frame DOM을 외부로 유출할 수 있었습니다. 기존 프로세스 모델 내에서의 cross-origin 정보 유출 우회에 해당하며, sandbox escape는 아닙니다. 한편 패치에서는 의도적으로 완화한 부분이 있습니다. 식별 불가능한 identifier(!frame)는 거부 대신 허용으로 처리되어, 이미 분리된(detached) 정상 frame이 영향을 받지 않도록 했습니다.
Note: writeWebContentToPasteboard 검사가 포함된 함수명, createOneWebArchiveFromFrames의 다른 프로세스로의 정확한 확산 동작 방식, 테스트에서의 구체적인 origin 구조는 commit 메시지와 코드 형태로부터 추론한 것으로, diff에서 직접 확인되는 내용은 아닙니다. 누락된 검사의 근본 원인과 거부 경로는 패치를 통해 직접 확인됩니다.
Audit directions
- 공격자가 제공한
FrameIdentifier를 기반으로 frame 또는 document 콘텐츠를 집계하거나 주소를 지정하면서,WebFrameProxy트리에 대한 subtree/ancestry 재검증이 없는 UI-process IPC handler. Site Isolation 하에서Vector<FrameIdentifier>또는FrameIdentifier를 key로 하는HashMap을 받는 다른WebPasteboardProxy및WebPageProxyhandler를 점검해야 합니다. 각 handler가WebFrameProxy::webFrame으로 identifier를 변환하고parentFrame()ancestry를 확인하는지 검증합니다. UIProcess 내.messages.in파일에서remoteFrameIdentifiers와FrameIdentifier파라미터를 검색하는 것부터 시작하는 것이 효과적입니다. - capability 검사에서 알 수 없는 identifier를 허용으로 처리하는 fail-open 기본값.
validateFrameIdentifiers내return !frame || isInSubtree(*frame)분기와, 식별 불가능한 identifier를 허용하는 유사 검사들을 살펴봐야 합니다. detached 또는 알 수 없는 frame이 콘텐츠를 유출하는 경로로 악용될 수 없는지 확인합니다.createOneWebArchiveFromFrames호출 지점을 추적하여, 지정된 frame identifier가 이후에 조회되거나 다른 프로세스에서 조회될 때 어떤 동작이 발생하는지 확인합니다. - 다른 WebContent process로 확산되는 cross-process archive/직렬화 집계 경로.
LegacyWebArchive조합 경로(createOneWebArchiveFromFrames,WebPlatformStrategies의collectFrameWebArchives)를 점검하여, 이번에 패치된 두 진입점뿐 아니라 모든 진입점에서 DOM이 수집되는 frame 집합이 요청 frame의 subtree 내로 한정되는지 확인합니다.