Protecting Browsers from Frame Hijacking Attacks
Many security-sensitive pages, such as login pages, contain inline frames (iframes). For example, the password-entry field on Google AdSense, Hushmail, and many bank web sites are contained in iframes. These frames appear to be part of the parent page and do not have address bars (or any kind of security indicator). Because the user has no visible indication of the source of the content that appears in the iframe, the user implicitly trusts the parent page to fill the iframe with trustworthy content. Protecting the integrity of the frame's contents is critical to the security of these sites.
Frame HijackingIn a frame hijacking attack, a malicious page navigates an iframe on a legitimate site to malicious content, such as a fake login form. These attacks are pixel-perfect because navigating an iframe neither alters the location bar nor disturbs the lock icon. For AdSense, if the login form is hijacked, the location bar still reads
https://www.google.com/adsense, the lock icon is displayed, and the certificate details list Google as the owner of the certificate.
Frame Navigation PoliciesBrowser frame navigation policies can be used to prevent frame hijacking attacks. The frame navigation policies of Internet Explorer, Opera, Firefox, and Safari are summarized below. We use the term active frame to refer to a frame that causes navigation to occur, while target frame refers to a frame being navigated.
Permissive policy A frame can navigate any other frame.IE6 has a preference option to replace the Permissive policy with a stricter policy:
Child policy A frame can navigate only its direct children.By default, Internet Explorer 7 implements the frame navigation policy below:
Descendant policy A frame can navigate only its descendants.IE7 also contains a preference option to revert to the Permissive policy.
window.opencircumvents this policy, reverting Opera to the Window policy (see below). Bug 13871, Mozilla attempted to implement the Child frame navigation policy. Unfortunately, by October 2001, the browser was still implementing the Permissive policy; see Bug 103638. This time, Mozilla implemented a restricted version of the following frame navigation policy:
Window policy A frame can navigate only frames in the same window.
Update 27 January 2008: Mozilla has adopted the Descendant policy in Firefox 3; see Bug 408052.
Safari 2 implements the Permissive policy. Safari 3 also implements the Permissive policy. We have collaborated with Apple to patch the trunk version of Safari 3 to implement the Descendant policy. As of 30 November 2007, the latest nightly build exhibits the Descendant policy.
Top-Level Frame NavigationMost browsers allow top-level frames to be navigated by anyone, because they have an address bar. However, Firefox places an additional restriction on navigation of top-level frames of other windows according to their opener:
Opener restriction An active frame can navigate a target top-level frame of another window only if
- the active frame is the target frame's opener.
Interaction with the Same-Origin PolicyUnder a strict interpretation of the Descendant policy, a frame is prevented from navigating its siblings directly, even if the frame is from the same origin its parent. In this situation, the frame can navigate its sibling indirectly by injecting script into its parent (this is permitted by the browser's scripting policy). The injected script can then navigate the sibling (this is permitted under the Descendant policy because the sibling frame is a descendant of the parent frame). In general, the browser should decided whether or not to permit a navigation based on a frame's security origin.
Origin propagation The browser should let an active frame navigate a target frame if there exists a frame such thatBy recognizing this origin propagation, browsers can achieve a better trade-off between security and compatibly by permitting navigations that do not sacrifice security. An attack can perform these navigation via a circuitous route, but allowing the direct navigations is more convenient for honest web developers.
- the frame is from the same origin as the active frame and
- the target frame is a descendant of the frame.
DiscussionFrame navigation policies balance usability and security. On one end of the spectrum, the Permissive policy admits serious attacks. On the other end, the Child policy without origin propagation blocks legitimate web site behavior. We summarize potential justifications for the three intermediate policies.
Child policyThe Child policy views frames as having an inner and outer component. Navigating either the inner or the outer component of the frame causes the frame to change location. An active frame that can script the target can navigate the inner component of the target. An active frame that can script the target's parent can navigate the outer component of the target.
Descendant policyThe Descendant policy views opening a frame to an origin as delegating control of a portion of the screen to that origin. If the active frame can script the target frame or one of its ancestors, it has been delegated authority over the target frame's portion of the screen and could simulate navigating the frame by positioning a floating iframe on top of the target frame.
Window policyThe Window policy views the top frame as being responsible for ensuring that malicious origins are not included in the frame hierarchy. This policy made sense when it was originally introduced, when frames were used primarily for navigation bars. However, in the current web there are many scenarios where the root page includes an iframe to untrusted content:
- Sites such as iGoogle or Live.com contain a number of iframe "gadgets." A malicious gadget can navigate all the other gadgets in the same window, tricking a user who is expecting to interact with some trusted gadgets (such as a Chat or Email gadget). For example, this iGoogle gadget hijacks all other non-inline gadgets in the current page (screenshot).
- Sites commonly display third-party advertisements in iframes. A malicious advertisement can navigate the other ad frames to steal their advertising impressions and display advertisements of the attacker's choice.
The Opener restriction is intended to restrict which active frames can navigate top-level windows. However, an active frame can bypass this restriction and navigate any top-level frame in the same unit of related browsing contexts:
An active frame can invade the root frame of a related browsing context by
window.topto get a reference to a top-level frame,
- dereferencing the
openerproperty of that frame and its openers until it reaches the root, and
- setting the root's
The root frame of the browsing context can navigate any open windows by recursively
window.opento navigate windows to its own origin. (Using
history.go(-1), any of these windows can be returned to their previous state.)
null. However, these countermeasures are not widely used today and may impair legitimate web functionality.
Because the Opener restriction can be circumvented unless the web site takes preventative measures, the Opener restriction provides similar security to a policy that restricts navigation to within a unit of related browsing contexts.
As of 29 April 2008, the HTML 5 specification recommends the Descendant policy. We recommend that Opera adopt the Descendant policy, matching Internet Explorer, Firefox, Safari, and HTML 5.
For more information, please see our full paper:
In Proceedings of the 17th USENIX Security Symposium (USENIX Security 2008)