[whatwg] Dealing with UI redress vulnerabilities inherent to the current web

Michal Zalewski lcamtuf at dione.cc
Thu Sep 25 10:24:04 PDT 2008

Hi folks,

I am posting here on the advice of Ian Hickson; I'm new to the list, so 
please forgive me if any of this brings up long-dismissed concepts; 
hopefully not.

For a couple of months now, along with a number of my colleagues at 
Google, we were investigating a security problem that we feel is very 
difficult or impossible to avoid on application side, and might be best 
addressed on HTML or HTTP level in contemporary browsers. These problems 
had recently gained some mainstream attention, and so we hoped to discuss 
potential solutions, and perhaps gain some traction for long-term fixes.

Problem definition: a malicious page in domain A may create an IFRAME 
pointing to an application in domain B, to which the user is currently 
authenticated with cookies. The top-level page may then cover portions of 
the IFRAME with other visual elements to seamlessly hide everything but a 
single UI button in domain B, such as "delete all items", "click to add 
Bob as a friend", etc. It may then provide own, misleading UI that implies 
that the button serves a different purpose and is a part of site A, 
inviting the user to click it. Although the examples above are naive, this 
is clearly a problem for a good number of modern, complex web 

Practical, real-world examples of such "UI redress" attacks were 
demonstrated in the past, and recently resurfaced on an OWASP conference 
(under the name of "clickjacking"); some references include:

  * http://www.thespanner.co.uk/2008/02/11/csrf-chat/
  * https://www.owasp.org/index.php/OWASP_NYC_AppSec_2008_Conference
  * http://lists.immunitysec.com/pipermail/dailydave/2008-September/005356.html

We feel that current web browser designs provide no adequate tools for web 
site owners to protect their applications against such attacks. The two 
workarounds often employed right now are:

1) Using Javascript hacks to detect that window.top != window to inhibit
    rendering, or override window.top.location. These mechanisms work only
    if Javascript is enabled, however, and are not guaranteed to be
    reliable or future-safe. If the check is carried on every UI click,
    performance penalties apply, too. Not to mention, the extra complexity
    is just counterintuitive and weird.

2) Requiring non-trivial reauthentication (captcha, password reentry) on
    all UI actions with any potential for abuse. Although this is
    acceptable for certain critical operations, doing so every time a
    person adds Bob as a friend on a social networking site, or deletes a
    single mail in a webmail system, is very impractical.

Other quick fixes are easy to come up with, but in general prove 
problematic in many usage scenarios. Based on our internal conversations, 
we have a number of proposals for approaches to how to address the issue, 
along with their pros and cons outlined. All these could be tweaked, 
combined, etc.; none of them seems quite ideal.

Proposed fixes:

1) Create a HTTP-level (or HTTP-EQUIV) mechanism along the lines of
    "X-I-Do-Not-Want-To-Be-Framed-Across-Domains: yes" that permits a web
    page to inhibit frame rendering in potentially dangerous situations.


    - Super-simple


    - "Opt-in", i.e. currently vulnerable sites remain vulnerable unless
      action is taken

    - Can't be used for cases where IFRAME content mixing has a legitimate
      purpose (for example, cross-domain gadgets, certain types of mashups)

    - Adds yet another security measure (along with cross-domain XHR, MSIE8
      XSS filters, MSIE P3P cookie behavior, Mozilla security policies)
      that needs to be employed correctly everywhere to work - which is
      very unlikely to consistently happen in practice

    - Along with the aforementioned security features, threatens to
      result in HTTP header or HTML HTTP-EQUIV size bloat that some sites
      may care about.

2) Add a document-level mechanism to make "if nested <show this> else
    <show that>" conditionals possible without Javascript. One proposal is
    to do this on the level of CSS (by using either the media-dependency
    features of CSS or special classes); another is to introduce new HTML
    tags. This would make it possible for pages to defend themselves even
    in environments where Javascript is disabled or limited.


    - Lightweight

    - Far more fine-grained than proposal #1 (though still not perfect)


    - "Opt-in" (sites remain vulnerable unless action is taken)

    - Might seem like an odd abuse of CSS / HTML

3) Add an on-by-default mechanism that prevents UI actions to be taken
    when a document tries to obstruct portions of a non-same-origin frame.
    By carefully designing the mechanism, we can prevent legitimate uses
    (such as dynamic menus that overlap with advertisements, gadgets, etc)
    from being affected, yet achieve a high reliability in stopping

    [ I like this one the most myself, but we were far from reaching any
      consensus. ]

    Algorithm description:

    A) Permit frames to be nested arbitrarily by default.

    B) If anything is to be drawn partly or fully on top of a region
       occupied by a nested IFRAME (in a callback from the renderer), look
       up the parent of the obstructing visual element drawn (that is, the
       party in charge of element's positioning). Always allow the element
       to be drawn, but if the parent is not same-origin with the target of
       an obstructed IFRAME, set a flag to disable UI input to that
       obstructed IFRAME (i.e., have the browser sink all UI events from
       now on). We may also gray out the disabled IFRAME (and maybe allow
       CSS to customize this behavior for specific IFRAMES).

    C) Treat a case where top-left corner of the IFRAME is drawn out of
       a visible area (CSS negative margins, etc) as a special case of
       being obstructed by the owner of a current rendering rectangle
       (another IFRAME or window.top) and carry out the same comparison.

    D) Once the obstruction is removed (say, a menu folded back), initiate
       a security timer (500-1000 ms or so) to eventually re-enable UI
       input to the IFRAME.

    E) Cases where a non-same-origin IFRAME is newly spawned by
       Javascript, or same-origin -> non-same-origin location updates takes
       place, should be treated as special cases of the IFRAME being
       uncloaked, and result in UI event lockout until a security timer

    F) Regardless of the aforementioned mechanism, do not permit an
       IFRAME target that is not same-origin with its parent document to
       invoke .focus() or to reposition content using URL anchors. This is
       to make sure that the top-left corner of the page as seen by the
       user always displays the top-left corner of the actual page.

    A potential optimization for D) and E), to minimize any potential
    impact where attacks are unlikely to succeed, is to:

    - Permit a short window of opportunity (0.5 second, perhaps)
      following initial page load, as well as possibly mouse clicks, during
      which cross-domain IFRAMEs may be revealed with no timer penalty,
      based on the assumption that immediate and involuntary UI actions
      are unlikely to follow.

    ...or alternatively:

    - Disable UI events or initiate timeouts only if cursor is within a
      certain radius of the uncloaked non-same-origin frame, based on the
      same assumption.


    - Works by default


    - Moderately complex and kludgy

    - In implementations, would require callbacks from the renderer to
      detect obstruction, as opposed to making decisions without this

    - Further investigation is needed to verify that this doesn't break the
      legitimate and common practice of some sites

4) Enforce a click-to-work mechanism (resembling the Eolas patent
    workaround) for all cross-domain IFRAMEs.


    - Works by default

    - Very simple


    - May be cumbersome for users

    - May not play well with gadgets, advertisements, etc.

5) Rework everything we know about HTML / browser security models to
    make it possible for domains and pages to specify very specific opt-in
    / opt-out policies for all types of linking, referencing, such that
    countering UI redress attacks would be just one of the cases controlled
    by this mechanism.


    - Awesome in theory, security-wise


    - Not really going to happen any time soon


More information about the whatwg mailing list