On Sep 25, 2008, at 10:24 AM, Michal Zalewski wrote:
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
attacks.
[ 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.
Isn't this likely to come up any time you have a scrollable iframe, or
one with overflow: hidden? And why top left but not bottom right?
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
expires.
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.
Pros:
- Works by default
Cons:
- Moderately complex and kludgy
- In implementations, would require callbacks from the renderer to
detect obstruction, as opposed to making decisions without this
knowledge
- Further investigation is needed to verify that this doesn't
break the
legitimate and common practice of some sites
I would add:
- Seems complicated to implement correctly.
- Seems very difficult to validate correctness of the security policy.
- Likely to break user experience of some existing sites.
I do not think this one is viable.
Regards,
Maciej