[8] safari-web-extension url masking bypass
Severity: Medium | Component: WebCore markup serialization | 3f52ce5
Rated Medium because the observable effect is a privacy-boundary leak of Safari Web Extension URLs through XMLSerializer and other DOM-to-string sinks, and impact is bounded to extension enumeration/fingerprinting (no memory-safety or sandbox-escape primitive).
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, ...);
Patch Details
Default ResolveURLs arguments across markup-serialization APIs flip from No/Yes to NoExcludingURLsForPrivacy/YesExcludingURLsForPrivacy. Touched declarations include Element::resolveURLStringIfNeeded, Element::completeURLsInAttributeValue, serializeFragment/serializePreservingVisualAppearance, HTMLImageElement::completeURLsInAttributeValue, LegacyWebArchive::createInternal/createFromSelection, and PageSerializer::SerializerMarkupAccumulator. A new XMLSerializer test asserts that webkit-masked-url://hidden/ survives and test-scheme:// does not.
Inconsistent application of a privacy-masking policy across sibling serialization sinks: the masking transform was applied on some DOM-to-string paths but skipped on others sharing the same input.
Background
Safari Web Extensions can inject DOM nodes whose attribute URLs resolve to extension-internal resources. To prevent web content from fingerprinting installed extensions, WebKit replaces extension URLs with webkit-masked-url://hidden/ whenever they are exposed back to web content. The ResolveURLs enum in Element.h has four members — No, NoExcludingURLsForPrivacy, Yes, YesExcludingURLsForPrivacy — where the *ExcludingURLsForPrivacy variants apply the masking transform during serialization.
Analysis
The masking policy was opt-in — ExcludingURLsForPrivacy had to be threaded explicitly through every DOM-to-string sink. The default was the non-privacy-aware variant, so any serializer that accepted the default leaked the underlying extension URL.
Aaa Aaaaaaa Aaaaaa a Aaaaaa Aaa Aaaaaaaaa Aaaaaaa Aaaaaa Aaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a Aaa Aaaa Aaaaaaa Aaaaaaaaa Aaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa a Aa Aaaaaaaa Aaaaaaaaaaaaaaaaaaa Aa Aa Aaaaaaaaa Aaaaaaaa Aaaaaaaaaaaaaa Aa Aaaaaaaaaaaaa Aaaaaa a Aaa Aaaaaa Aaa Aaaaaaaa Aaaaaaaaa Aaa Aaa Aa Aaa Aaaaaaaa Aaaaaa Aa Aaaaaaa Aaa Aaaaaaaaa Aaaaaaaaaa Aaa Aaaaaaaa Aaaaaa Aaa Aaaaa Aaaa Aaaaaaaaaaaa Aaaaaaa Aaaa Aaaaaa Aaaaaaa Aaa Aaaaaaaaaa Aaaaaa Aaaaaaaa Aaaaaaaaaaaaaaaaa Aaaaaaaa Aa Aaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaa Aaaaaaa Aaaaaaaa Aaaaaaa Aaaaaaaaaa Aaa Aaaaaaaaa Aaa Aaaaaaaa Aaa Aaa Aaaaaa Aaa Aaaaaaaaaaaaa Aaaaaaa Aaa Aaaaaaa Aa Aaa Aaaaa Aaaaaaaaaa Aaaaa Aaa Aaa Aaaa Aaaa Aaaaaaaa Aaa Aaaaaa Aa Aaa Aaaaaaaa Aaa Aaaa Aaaaaa Aaaaaaaa Aa Aaaaa Aaaaa Aaaa Aaaaaaa Aaaaaa Aaaaaaa a Aaaaaa Aaaaaaa Aa Aaaaaaa Aa Aaaaaaaaaaaaa
🔒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.
Subscribe to read more
Audit directions
a Aaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaaaaaa Aa Aaaaaa Aaaa Aaaaaaaa Aaaaaa Aaaaaaaa Aa Aaaaa Aaaa Aaaa Aaaaaaa Aa Aaa Aaaaa Aaaa Aaa Aaaaaaaa Aaaaaaaaaaaaaaaaaaa a Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aa Aaaaaaaaaaaaaaaa Aaa Aaaaaa Aaaa Aa Aaaaaaaaaaaa
a Aaaaaaaaaaaaaaa Aaaaa Aaaa Aaaaaa Aaaaaa Aaaaaaa a Aaaaaa Aaaaaaa Aaaaaaaaa Aaaaaa Aaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaa a Aaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaaaaa Aaaaaaaaaaaaa Aaaaaaaaa Aaaaaaaaaaaaaaaaa Aaaaaaaaa Aaa Aaaaaaaaaaaaaa Aaaaaaaaaaaaa Aaaa Aaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaaaaaaaaa Aaaaaaa Aaaaaaa Aaaaaa Aaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaaaa Aaaaaaaaa Aaaaaaa Aaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
a Aaaaaaaaaa Aaaa Aaaa Aa Aaaa Aa Aaaaaaa Aaa Aaaaaaaaaa Aaaaaa Aaaaaaa Aaaaaaaaaaaaa Aaa Aa Aaaaaaa Aa Aaa Aaaaaaaa Aaaa Aaaaaaa Aaaaaa Aaaaaaaa
🔒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.
Subscribe to read more