← All issues

[2] Attachment-element arbitrary file read via unvalidated IPC path

An <attachment> can be backed by a file on disk — and the UIProcess never checked whether the renderer had actually been handed that path.

Severity: High | Component: WebKit UIProcess attachment handling | c6cd4e0

diff가 추가한 provenance check는 이전까지 누락된 상태였으며, 이로 인해 침해된 renderer가 UI process 수준에서 읽을 수 있는 임의의 파일을 지목하고 그 내용을 attachment에 바인딩하는 것이 가능했습니다. sandbox 파일시스템 탈출로 이어지는 information leak으로 확장되려면 사전 renderer 침해만 전제되면 충분하며, /etc/passwd regression test가 해당 경로의 실제 도달 가능성을 뒷받침합니다.

WebProcessProxy에는 pasteboard 및 drag-drop 작업을 통해 web process에 정당하게 제공된 경로를 추적하는 파일 경로 allowlist(m_allowedAttachmentFilePaths)가 추가되었습니다. RegisterAttachmentIdentifierFromFilePath에서는 MESSAGE_CHECK를 통해 수신된 경로를 이 allowlist와 대조하며, 허가되지 않은 경로에 대해서는 web process를 종료합니다.

Source/WebKit/UIProcess/WebPageProxy.cpp

void WebPageProxy::registerAttachmentIdentifierFromFilePath(IPC::Connection& con...
{
MESSAGE_CHECK_BASE(protect(preferences())->attachmentElementEnabled(), connection);
MESSAGE_CHECK_BASE(IdentifierToAttachmentMap::isValidKey(identifier), connection);
+ MESSAGE_CHECK_BASE(WebProcessProxy::fromConnection(connection)->isAllowedAttachmentFilePath(filePath), connection);
...
+#if ENABLE(ATTACHMENT_ELEMENT)
+ for (auto& filename : dragData.fileNames())
+ protect(protectedThis->legacyMainFrameProcess())->addAllowedAttachmentFilePath(filename);
+#endif

Source/WebKit/UIProcess/WebProcessProxy.cpp

+void WebProcessProxy::addAllowedAttachmentFilePath(const String& filePath)
+{
+ if (!filePath.isEmpty())
+ m_allowedAttachmentFilePaths.add(filePath);
+}
+bool WebProcessProxy::isAllowedAttachmentFilePath(const String& filePath) const
+{
+ return m_allowedAttachmentFilePaths.contains(filePath);
+}

Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WKAttachmentTests.mm

+ [webView evaluateJavaScript:
+ @"IPC.sendMessage('UI', IPC.webPageProxyID, IPC.messages.WebPageProxy_RegisterAttachmentIdentifierFromFilePath.name, ["
+ " {type: 'String', value: 'fake-identifier'},"
+ " {type: 'String', value: 'application/octet-stream'},"
+ " {type: 'String', value: '/etc/passwd'}"
+ "])"
+ completionHandler:nil];
+ [navigationDelegate waitForWebContentProcessDidTerminate];

이번 patch는 WebProcessProxyHashSet<String> m_allowedAttachmentFilePaths를 추가했습니다. 이 집합은 UI process가 web process에 실제 파일시스템 경로를 전달하는 모든 정당한 지점에서 채워집니다. drag-drop 시에는 performDragOperationdragData.fileNames()를 순회하며 경로를 추가하고, pasteboard 읽기 시에는 WebPasteboardProxyCocoa.mm에서 새로 도입된 addAllowedAttachmentFilePaths helper를 통해 추가됩니다. registerAttachmentIdentifierFromFilePath에는 MESSAGE_CHECK_BASE(... isAllowedAttachmentFilePath(filePath), connection)가 추가되어, 정당하게 허용된 적 없는 경로에 대해 web process를 종료합니다. 보조적인 강화 조치로 registerAttachmentsFromSerializedData에도 isValidKey 검사가 추가되었습니다.

WebContent → UIProcess IPC 경계를 넘는 파일시스템 경로에 대한 provenance 검증 누락 — sandbox 내 송신자가 허가받지 않은 파일을 지목할 수 있었던 패턴.

WebProcessProxy는 하나의 web content process를 대표하는 UI process 측 객체로, WebContent sandbox 밖에서 사용자의 전체 권한으로 실행됩니다. <attachment> element의 backing data는 디스크 상의 파일이 될 수 있으며, 해당 파일은 식별자를 통해 등록됩니다. registerAttachmentIdentifierFromFilePath는 web process가 제공한 경로를 받아 attachment를 생성하는 UI process 측 IPC handler입니다. UI process가 renderer에 실제 파일시스템 경로를 노출하는 정당한 경우는 사용자가 파일을 drag-drop하거나 파일 URL을 붙여넣을 때뿐입니다. 이때 UI process는 sandbox extension을 통해 해당 경로들만 한정적으로 공유합니다. MESSAGE_CHECK_BASE는 assertion이 실패할 경우 송신 process를 종료합니다.

전형적인 confused-deputy / IPC 검증 누락 유형의 버그입니다. 패치 이전에는 registerAttachmentIdentifierFromFilePath가 renderer로부터 임의의 filePath 문자열을 받아 해당 경로를 backing으로 하는 attachment를 등록했습니다. UI process가 해당 경로를 정당하게 노출한 적이 있는지는 전혀 확인하지 않았습니다. 누락된 불변 조건은 다음과 같습니다. attachment 생성에 사용되는 파일 경로는 반드시 실제 사용자 행위(drag-drop 또는 pasteboard 읽기)를 통한 허가로 소급되어야 합니다.

UI process는 WebContent sandbox 밖에서 실행되며, 사용자가 읽을 수 있는 모든 파일에 접근할 수 있습니다. 침해된 renderer가 /etc/passwd와 같이 attacker가 선택한 절대 경로를 담아 RegisterAttachmentIdentifierFromFilePath를 전송하면, UI process는 해당 파일을 열고 그 내용을 attachment 식별자에 바인딩하게 됩니다. 이후 web content는 attachment.info.data를 통해 해당 데이터를 조회할 수 있어, UI process 수준의 파일 읽기가 WebContent에서 관찰 가능한 information leak으로 이어집니다. 이는 memory corruption이 아닌 arbitrary file read / sandbox 파일시스템 탈출 primitive에 해당하며, IPC handler에 도달하려면 WebContent 사전 침해가 전제되어야 합니다. 다만 diff에는 추가된 MESSAGE_CHECK 라인만 드러나 있어, 파일 열기 및 반환 본문과 attachment.info.data 조회 경로는 test 코드로부터 추론한 사항이며 diff에서 직접 확인되지는 않습니다.

이 vulnerability는 WebContent와 UIProcess 사이의 sandbox 경계를 약화시킵니다. 보안 모델의 전제는 UI process가 사용자 매개 작업을 통해 직접 허용한 파일시스템 경로에 대해서만 동작한다는 것입니다. 패치 이전에는 attachment 등록 과정에서 이 불변 조건이 강제되지 않았습니다. 결과적으로 침해된 renderer에게 renderer의 파일시스템 격리를 벗어나는 arbitrary file read 능력이 사실상 부여되었으며, 자격증명이나 토큰 탈취에 활용될 가능성이 있습니다.