HTML frames (FRAMESETs and IFRAMEs) are a feature of all modern web browsers that enable content from multiple pages to be displayed within a single view. Historically, frames were primarily used to enable partial page updates, where page navigation was contained in one frame, and page content was contained in another. Over time, use of frames expanded to include advertising, mashup, and AJAX scenarios. Today, the majority of popular websites use IFRAMEs for myriad reasons.
From a security point of view, frames can help increase the security of web applications by creating isolation between content delivered from different sources. For instance, a Web mail account (http://mail.example.com) might choose to render HTML email within an IFRAME (http://untrusted.example.com/getmsg?msgid=1234) to ensure that any script in the HTML mail cannot execute in the context of the Web mail application delivered from mail.example.com. Instead, any script would execute in the context of the “untrusted.example.com” domain. This isolation prevents tampering with the Web mail UI, leaking user credentials and cookies, snooping on other messages, etc.
For frames rendered in Internet Explorer 6 and later, security can be further increased by setting the frame’s SECURITY attribute to the value “restricted”. Doing so causes Internet Explorer to treat the contents of the frame, regardless of their source, as content that should be rendered in the Restricted Sites Security Zone. Frames running in the Restricted Sites zone cannot run script, invoke ActiveX controls, redirect to other sites, and so on. This technique is particularly useful in cases where the frame’s content cannot be assumed to be trustworthy (as in the case of web mail scenario above).
However, it is important to understand that HTML frames are not a security panacea. In order to remain secure, a website which chooses to include content from another website in a frame must generally trust that other website to be non-malicious. Otherwise, a number of security threats are exposed.
For instance, consider a web mail application containing two IFRAMEs: one that is used to display an advertisement, and one that is used to display the contents of an HTML email.
<iframe src="http://ad.example.com/rand/1234.aspx" security="restricted"></iframe>
<iframe src="http://untrusted.example.com/getmsg?msgid=1234" security="restricted"></iframe>
In the best case, both frames are tagged with the SECURITY="restricted" attribute to ensure that the HTML email or the advertisement cannot contain any script which might be used to navigate the user away from the web mail page to a malicious site (e.g. <SCRIPT>window.location="http://evil.example.net/malice.htm"</SCRIPT>).
The user will likely recognize that the email frame contains content of questionable trustworthiness. While the email may contain a phishing attack or other malicious content, it is unlikely that the user will mistake such content as a part of the web mail application itself. In contrast, in the advertising case, unless there is an indication around the IFRAME indicating that the contents are an advertisement, the user could be fooled into taking an unsafe action. For instance, an ad banner could be crafted to match the web mail user-interface, containing text that suggests that there’s a system outage and the user should email their name and password to a given address. The user may mistake the content as a trusted message from the web mail application, and undertake an unsafe action.
Therefore, Web developer best practices for using frames can be summarized as:
- If possible, do not include frames containing content from unknown/untrusted sites.
- If possible, use the SECURITY="restricted"attribute to reduce the privileges of content in the IFRAME.
- If it is not already obvious to users, clearly mark any frames containing untrusted content.
edit: adjusted quotes around "restricted"