Stanford Web Security Research

Protecting Browsers from Frame Hijacking Attacks

Adam Barth, Collin Jackson
12 December 2007
Updated 29 April 2008

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 Hijacking

In 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 Policies

Browser 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.

Internet Explorer

By default, Internet Explorer 6 implements a permissive frame navigation policy:
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.

Opera

Opera 9 attempts to implement the Child frame navigation policy. Unfortunately, calling window.open circumvents this policy, reverting Opera to the Window policy (see below).

Firefox

Prior to October 2000, Mozilla implemented the Permissive policy. In response to 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

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.

Update 18 December 2007: Apple has deployed the Descendant policy in Safari as part of Security Update 2007-009 (CVE-2007-5858).

Top-Level Frame Navigation

Most 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
  1. the active frame has a JavaScript reference to the target frame or
  2. the active frame is the target frame's opener.

Interaction with the Same-Origin Policy

Under 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 that
  1. the frame is from the same origin as the active frame and
  2. the target frame is a descendant of the frame.
By 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.

Discussion

Frame 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 policy

The 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 policy

The 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 policy

The 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:
  1. 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).
  2. 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.

Opener restriction

Most browsers permit navigation of top-level frames because their location is displayed to the user in the location bar. If an attacker attempts to hijack a top-level frame, the attack will be evident by the new URL that appears in the location bar.

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:

  1. An active frame can invade the root frame of a related browsing context by
    1. dereferencing window.top to get a reference to a top-level frame,
    2. dereferencing the opener property of that frame and its openers until it reaches the root, and
    3. setting the root's location property.
  2. The root frame of the browsing context can navigate any open windows by recursively using window.open to navigate windows to its own origin. (Using history.go(-1), any of these windows can be returned to their previous state.)
Sites can sever ties with related browsing contexts by opening only anonymous windows and by setting their window.opener to 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.

Recommendation

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:

pdf
Securing Frame Communication in Browsers   [BIBTEX]