[10] XMLSerializer Extension URL Leak
Severity: Medium | Component: WebCore XML serialization | 0f4832c
웹 페이지 어디서든 단일 JavaScript 호출만으로 extension fingerprinting을 간단히 수행할 수 있습니다. 다만 영향 범위가 정보 노출(extension 식별)에 한정되고 memory corruption이나 code execution은 수반되지 않으므로 Medium으로 분류됩니다.
XMLSerializer에서 custom scheme URL을 마스킹하여 버그를 수정하였습니다.
Source/WebCore/xml/XMLSerializer.cpp
String XMLSerializer::serializeToString(Node& node)
{
- return serializeFragment(node, SerializedNodes::SubtreeIncludingNode, nullptr, ResolveURLs::No, SerializationSyntax::XML);
+ return serializeFragment(node, SerializedNodes::SubtreeIncludingNode, nullptr, ResolveURLs::NoExcludingURLsForPrivacy, SerializationSyntax::XML);
}
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewConfiguration.mm
+ NSString *xmlSource = [webView stringByEvaluatingJavaScript:@"(new XMLSerializer()).serializeToString(document.body)"];
+ EXPECT_WK_STREQ(xmlSource, @"<body xmlns=\"http://www.w3.org/1999/xhtml\"><iframe src=\"webkit-masked-url://hidden/\"></iframe><iframe src=\"http://apple.com/baz.html\"></iframe></body>");
대체 DOM 직렬화 경로에서 누락된 privacy URL 마스킹.
Patch Details
변경 내용 자체는 단순합니다. XMLSerializer::serializeToString이 serializeFragment를 호출할 때 전달하던 ResolveURLs::No 값을 ResolveURLs::NoExcludingURLsForPrivacy로 교체한 것이 전부입니다. 이를 통해 web extension이 사용하는 custom scheme URL은 직렬화 결과물에서 webkit-masked-url://hidden/으로 대체되는데, 추가된 테스트에서 extension URL의 마스킹과 일반 http:// URL의 원형 보존이 함께 이루어짐을 확인할 수 있습니다.
Background
WebKit은 privacy 보호 메커니즘으로 URL 마스킹을 지원합니다. web extension이 custom URL scheme(예: another-scheme://foo.com/bar.js)을 사용해 콘텐츠를 주입하는 경우, 브라우저는 DOM 직렬화 시 해당 URL을 webkit-masked-url://hidden/으로 대체합니다. 이 방식으로 웹 페이지가 설치된 extension을 fingerprinting하는 경로를 차단하게 됩니다. ResolveURLs enum이 이 동작을 제어하는데, ResolveURLs::No는 URL을 그대로 직렬화하는 반면, ResolveURLs::NoExcludingURLsForPrivacy는 relative URL은 보존하되 private custom scheme URL은 마스킹합니다. innerHTML 직렬화 경로에서는 이미 후자의 variant를 사용하고 있었습니다.
Analysis
이 문제의 근본 원인은 대체 경로를 통한 우회에 있습니다. privacy 메커니즘은 innerHTML 직렬화에는 적용되어 있었지만, XMLSerializer는 동일한 serializeFragment 함수를 다른 enum 파라미터로 호출하는 경로라는 점에서 예외였습니다. 어느 웹 페이지에서든 new XMLSerializer().serializeToString(document.body)를 호출하면 설치된 browser extension의 실제 custom scheme URL이 복원되며, 어떤 extension이 설치되어 있는지와 각 extension의 내부 URL 구조까지 노출됩니다.
Aa Aaa Aaaaaa Aaaaaaaaaa Aaa Aaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a a Aaaa Aaaa Aaaaa Aa Aaaaaa Aaaaaa Aaaa Aaaaaa Aaaaaaaaa Aaaaaaaaaaaaaaa Aa Aaaa Aaa a Aaaa Aaa Aaa Aaaaaaaaaa Aaaa Aaaaaaaa Aaaaaaa Aaa Aaaaaaaaa Aaa Aaaaa Aaaaaaa Aaaaaaaaaaaa Aaa Aaa Aaa Aaa Aa Aaa Aaaa Aaaaaa Aaaaaaaaaaaa Aaaa Aaaaaaaa Aa a Aaaaa
a Aaaaaaaaaaaaaa Aaa Aaaaaaaaaa Aaa Aaaaaa Aaa Aaaaaaaa Aaaaaaa Aaa Aaaa Aaaaaaaa Aa Aaaaaaa Aaa Aaa Aa Aa Aa Aaa Aaaa Aaa Aa Aaa Aaa Aaaa Aaaa Aaaa Aa Aaa Aaa Aa Aa Aaaaaa Aaaaaaaaa Aaaa Aaaa Aaa Aaa Aaa Aaaaaa Aaaaaa
Audit directions
a Aaa Aaa Aa Aaa Aa Aa Aaaaa Aaaa Aa Aaa Aaaaaaaaaaaaaaaa Aaa Aaa Aaaaaa Aaaaaaaaa Aaaaaaaaaaaaaaaaaaaa Aaaa Aa Aaa Aaaaa Aaa Aaa Aaaaaaaaa Aa Aaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaaa Aaaa Aaaaa Aaaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaa Aaaa Aa Aaa Aaa a Aaaaa
a Aaa Aaa Aa Aaaa Aa Aaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaa Aa Aaaa Aaa Aaaa Aaaa Aa Aaaaa Aaa Aaaaa Aaaa Aaaa Aaa Aaaa Aaaa Aaaaaaaaaaaaaaaa Aaaa Aa Aaaaaaaaaaaaaaaaaaa Aaa Aaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaaaa Aa Aaaaaaaaaaaaaaaaaaaaaa Aa Aa Aaaaaa Aaa Aaaa Aa Aaa Aaaa Aaa Aa Aaaa Aaaaaa Aaaaaa Aaaa Aaaa Aaa Aaa Aaa Aaaaa