WebKit: UXSS through HTMLObjectElement::updateWidget CVE-2017-2493 When an object element loads a JavaScript URL(e.g., javascript:alert(1)), it checks whether it violate the Same Origin Policy or not. Here's some snippets of the logic. void HTMLObjectElement::updateWidget(CreatePlugins createPlugins) { ... String url = this->url(); ... if (!allowedToLoadFrameURL(url)) return; ... bool beforeLoadAllowedLoad = guardedDispatchBeforeLoadEvent(url); ... bool success = beforeLoadAllowedLoad && hasValidClassId(); if (success) success = requestObject(url, serviceType, paramNames, paramValues); ... } bool HTMLPlugInImageElement::allowedToLoadFrameURL(const String& url) { URL completeURL = document().completeURL(url); if (contentFrame() && protocolIsJavaScript(completeURL) && !document().securityOrigin().canAccess(contentDocument()->securityOrigin())) return false; return document().frame()->isURLAllowed(completeURL); } bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType, const Vector& paramNames, const Vector& paramValues) { if (m_pluginReplacement) return true; URL completedURL; if (!url.isEmpty()) completedURL = document().completeURL(url); ReplacementPlugin* replacement = pluginReplacementForType(completedURL, mimeType); if (!replacement || !replacement->isEnabledBySettings(document().settings())) return false; LOG(Plugins, "%p - Found plug-in replacement for %s.", this, completedURL.string().utf8().data()); m_pluginReplacement = replacement->create(*this, paramNames, paramValues); setDisplayState(PreparingPluginReplacement); return true; } The SOP violation check is made in the method HTMLPlugInImageElement::allowedToLoadFrameURL. What I noticed is that there are two uses of |document().completeURL| for the same URL, and the method guardedDispatchBeforeLoadEvent dispatches a beforeloadevent that may execute JavaScript code after the SOP violation check. So if the base URL is changed like "javascript:///%0aalert(location);//" in the event handler, a navigation to the JavaScript URL will be made successfully. Tested on Safari 10.0.3(12602.4.8). PoC: This bug is subject to a 90 day disclosure deadline. If 90 days elapse without a broadly available patch, then the bug report will automatically become visible to the public. Found by: lokihardt