← All issues

[8] safari-web-extension url masking bypass

Severity: Medium | Component: WebCore markup serialization | 3f52ce5

Observable effect는 XMLSerializer 및 기타 DOM-to-string sink를 통한 Safari Web Extension URL의 privacy 경계 노출입니다. Impact는 extension 열거 및 fingerprinting에 한정되며, memory safety나 sandbox escape primitive는 존재하지 않습니다. 이를 근거로 Medium으로 평가합니다.

Source/WebCore/dom/Element.h

- String resolveURLStringIfNeeded(const String& urlString, ResolveURLs = ResolveURLs::Yes, const URL& base = URL()) const;
- virtual String completeURLsInAttributeValue(const URL& base, const Attribute&, ResolveURLs = ResolveURLs::Yes) const;
+ String resolveURLStringIfNeeded(const String& urlString, ResolveURLs = ResolveURLs::YesExcludingURLsForPrivacy, const URL& base = URL()) const;
+ virtual String completeURLsInAttributeValue(const URL& base, const Attribute&, ResolveURLs = ResolveURLs::YesExcludingURLsForPrivacy) const;

Source/WebCore/editing/markup.h

-WEBCORE_EXPORT String serializeFragment(const Node&, SerializedNodes, Vector<Ref<Node>>* = nullptr, ResolveURLs = ResolveURLs::No, ...);
+WEBCORE_EXPORT String serializeFragment(const Node&, SerializedNodes, Vector<Ref<Node>>* = nullptr, ResolveURLs = ResolveURLs::NoExcludingURLsForPrivacy, ...);

Markup serialization API 전반에 걸쳐 ResolveURLs의 기본 인자가 No/Yes에서 NoExcludingURLsForPrivacy/YesExcludingURLsForPrivacy로 변경되었습니다. 변경 대상에는 Element::resolveURLStringIfNeeded, Element::completeURLsInAttributeValue, serializeFragment/serializePreservingVisualAppearance, HTMLImageElement::completeURLsInAttributeValue, LegacyWebArchive::createInternal/createFromSelection, PageSerializer::SerializerMarkupAccumulator 선언이 포함됩니다. 새로 추가된 XMLSerializer 테스트에서는 webkit-masked-url://hidden/이 그대로 유지되고 test-scheme://는 그렇지 않음을 확인할 수 있습니다.

동일한 입력을 공유하는 serialization sink들 사이에서 privacy masking 정책이 일관되게 적용되지 않았습니다. 일부 DOM-to-string 경로에는 masking transform이 적용되었지만, 나머지 경로에서는 누락된 상태였습니다.

Safari Web Extensions는 extension 내부 리소스를 가리키는 URL을 attribute로 갖는 DOM 노드를 삽입할 수 있습니다. 설치된 extension을 web content가 fingerprinting하지 못하도록, WebKit은 extension URL이 web content에 노출될 때 webkit-masked-url://hidden/으로 대체합니다. 이 동작을 제어하는 것이 Element.hResolveURLs enum입니다. 해당 enum은 No, NoExcludingURLsForPrivacy, Yes, YesExcludingURLsForPrivacy의 네 가지 값으로 구성되며, *ExcludingURLsForPrivacy 변형이 직렬화 시 masking transform을 담당합니다.

Masking 정책이 opt-in으로 설계되었다는 점이 핵심입니다. ExcludingURLsForPrivacy를 각 DOM-to-string sink에 명시적으로 전달하지 않으면 masking이 적용되지 않으며, 기본값을 그대로 사용하는 serializer는 extension URL을 외부에 그대로 노출하게 됩니다.

🔒

Walks through how a privacy-masking policy applied at some serialization sinks but not others created a uniform bypass, and what an attacker observes in practice.

더 확인하려면 구독해 주세요

🔒

Multiple audit patterns identified covering opt-in security defaults, DOM-to-string sinks beyond the patched ones, and non-markup leakage paths for the same sensitive data.

더 확인하려면 구독해 주세요