There are numerous mechanisms that permit HTML web pages to include and display remote sub-resources through HTTP GET requests without having these operations subjected to a well-defined set of security checks: - Remote scripts: <SCRIPT SRC="..."> tags may be used to issue GET requests to arbitrary sites, likewise. A relatively relaxed JavaScript
(or E4X XML) parser is then applied to the received content; if the
response passes off as something resembling structurally sound JavaScript,
this cross-domain payload may then be revealed to other scripts on the
current page; one way to achieve this goal is through redefining
callback functions or modifying object prototypes; some browsers
further help by providing verbose error messages to onerror
handlers. The possibility of cross-domain data inclusion poses a risk
for all sensitive, cookie-authenticated JSON interfaces, and some other
document formats not originally meant to be JavaScript, but resembling it in some aspects (e.g., XML, CSV).Note:
quite a few JSON interfaces not intended for cross-domain consumption
rely on a somewhat fragile defense: the assumption that certain very
specific object serializations ({ param: "value"}) or meaningless prefixes (&&&START&&&) will not parse via <SCRIPT SRC="...">; or that endless loop prefixes such as while (1)
will prevent interception of the remainder of the data. In most cases,
these assumptions are not likely to be future-safe; a better option is
to require custom XMLHttpRequest headers, or employ a parser-breaking prefix that is unlikely to ever work as long as the basic structure of JavaScript is maintained. One such example is the string of )]}', followed by a newline.
- Remote stylesheets: <LINK REL="stylesheet" HREF="..."> tags may be used in a manner similar to <SCRIPT>. The returned data would be subjected to a considerably more rigorous CSS syntax
parser. On one hand, the odds of a snippet of non-CSS data passing this
validation are low; on the other, the parser does not abort on the
first syntax error, and continues parsing the document unconditionally
until EOF - so scenarios where some portions of a remote document
contain user-controlled strings, followed by sensitive information, are
of concern. Once properly parsed, CSS data may be disclosed to
non-same-origin scripts through getComputedStyle or currentStyle properties (the former is W3C-mandated). One potential attack of this type was proposed by Chris Evans; in Internet Explorer, the impact may be greater due to the more relaxed newline parsing rules.
- Embedded objects and applets: <EMBED SRC="...">, <OBJECT CODEBASE="...">, and <APPLET CODEBASE="..."> tags permit arbitrary resources to be retrieved via GET
and then supplied as input to browser plugins. The exact effect of this
action depends on the plugin to which the resource is routed, a factor
entirely controlled by the author of the page. The impact is that
content never meant to be interpreted as a plugin-based program may end
up being interpreted and executed in a security context associated with
the serving host.
- Document-embedded frames: <FRAME> and <IFRAME>
elements may be used to create new document rendering containers within
the current browser window, and to fetch any target documents via GET. These documents would be subject to same-origin checks once loaded.
Note that on all of the aforementioned inclusion schemes other than <FRAME> and <IFRAME>, any Content-Type and Content-Disposition
HTTP headers returned by the server for the sub-resource are mostly
ignored; there is no opportunity to authoritatively instruct the
browser about the intended purpose of a served document to prevent
having the data parsed as JavaScript, CSS, etc. In
addition to these content inclusion methods, multiple ways exist for
pages to initiate full-page transitions to remote content (which causes
the target document for such an operation to be replaced with a brand
new document in a new security context): - Link targets: the current document, any other named window or frame, or one of special window classes (_blank, _parent, _self, _top) may be targeted by <A HREF="..."> to initiate a regular, GET-based page transition. In some browsers, such a link may be also automatically "clicked" by JavaScript with no need for user interaction (for example, using the click() method).
- Refresh and Location directives: HTTP Location and Refresh headers, as well as <META HTTP-EQUIV="Refresh" VALUE="..."> directives, may be used to trigger a GET-based page transition, either immediately or after a predefined time interval.
- JavaScript DOM access: JavaScript code may directly access location.*, window.open(), or document.URL to automatically trigger GET page transitions, likewise.
Form submission: HTML <FORM ACTION="..."> tags may be used to submit POST and GET requests to remote targets. Such transitions may be triggered automatically by JavaScript by calling the submit() method. POST forms may contain payloads constructed out of form field name-value pairs (both controllable through <INPUT NAME="..." VALUE="..."> tags), and encoded according to application/x-www-form-urlencoded ( name1=value1&name2=value2..., with %nn encoding of non-URL-safe characters), or to multipart/form-data (a multipart MIME-like format), depending on ENCTYPE= parameter.In addition, some browsers permit text/plain to be specified as ENCTYPE; in this mode, URL encoding is not applied to name=value pairs, allowing almost unconstrained cross-domain POST payloads. Trivia: POST payloads are opaque to JavaScript.
Without server-side cooperation, or the ability to inspect the
originating page, there is no possibility for scripts to inspect the
data posted in the request that produced the current page. The property
might be relied upon as a crude security mechanism in some specific
scenarios, although it does not appear particularly future-safe.
Related tests: Test description | MSIE6 | MSIE7 | MSIE8 | FF2 | FF3 | Safari | Opera | Chrome | Android | Are verbose onerror messages produced for <SCRIPT>? | YES | YES | YES | YES | NO | NO | NO | NO | NO | Are verbose onerror messages produced for <STYLE>? | NO | NO | NO | NO | NO | NO | NO | NO | NO | Can links be auto-clicked via click()? | YES | YES | YES | NO | NO | NO | YES | NO | NO | Is getComputedStyle supported for CSS? (W3C) | NO | NO | NO | YES | YES | YES | YES | YES | YES | Is currentStyle supported for CSS? (Microsoft) | YES | YES | YES | NO | NO | NO | YES | NO | NO | Is ENCTYPE=text/plain supported on forms | YES | YES | YES | YES | YES | NO | YES | NO | NO |
Note that neither of the aforementioned methods permits any control over HTTP headers. As noted earlier, more permissive mechanisms may be available to plugin-interpreted programs and other non-HTML data, however. Yet another operation permitted across domains with no specific security checks is the ability to seamlessly merge <IFRAME>
containers displaying chunks of third-party sites (in their respective
security contexts) inside the current document. Although this feature
has no security consequences for static content - and in fact, might be
desirable - it poses a significant concern with complex web
applications where the user is authenticated with cookies: the attacker
may cleverly decorate portions of such a third-party UI to make it
appear as if they belong to his site instead, and then trick his
visitors into interacting with this mashup. If successful, clicks would
be directed to the attacked domain, rather than attacker's page - and
may result in undesirable and unintentional actions being taken in the
context of victim's account. There are several basic ways to fool users into generating such misrouted clicks: - Race condition attacks:
lastly, the attacker may simply opt for hiding the target UI (as a
frame, or as a separate window) underneath his own, and reveal it only
miliseconds before the anticipated user click, not giving the victim
enough time to notice the switch, or react in any way. Scripts have the
ability to track mouse speed and position over the entire document, and
close or rearrange windows, but it is still relatively difficult to
reliably anticipate the timing of single, casual clicks. Timing
solicited clicks (e.g. in action games) is easier, but there is a
prerequisite of having an interesting and broadly appealing game to
begin with.
In all cases, the attack is challenging to
carry out given the deficiencies and incompatibilities of CSS
implementations, and the associated difficulty of determining the exact
positioning for the targeted UI elements. That said, real-world
exploitation is not infeasible. In two of the aforementioned attack
scenarios, the fact that that the invisible container may follow mouse
pointer on the page makes it somewhat easier to achieve this goal, too.
Also note that the same UI redress possibility applies to <OBJECT>, <EMBED>, and <APPLET> containers, although typically with fewer security implications, given the typical uses of these technologies. UI redress attacks gained some prominence in 2008, after Jeremiah Grossman and Robert 'RSnake' Hansen coined the term clickjacking and presented the attack to the public. Discussions with browser vendors on possible mitigations are taking place (example),
but no definitive solutions are to be expected in the short run. So
far, the only freely available product that offers a reasonable degree
of protection against the possibility is NoScript
(with the recently introduced ClearClick extension). To a much lesser
extent, on opt-in defense is available Microsoft Internet Explorer 8,
Safari 4, and Chrome 2, through a X-Frame-Options header (reference), enabling pages to refuse being rendered in any frames at all (DENY), or in non-same-origin ones only (SAMEORIGIN). On the flip side, only a single case of real-world exploitation is publicly known as of this writing. In
absence of browser-side fixes, there are no particularly reliable and
non-intrusive ways for applications to prevent attacks; one possibility
is to include JavaScript to detect having the page rendered within a cross-domain <IFRAME>, and try to break out of it, e.g.: try { if (top.location.hostname != self.location.hostname) throw 1; } catch (e) { top.location.href = self.location.href; } It should be noted that there is no strict guarantee that the update of top.location would always work, particularly if dummy setters are defined, or if there are collaborating, attacker-controlled <IFRAME>
containers performing conflicting location updates through various
mechanisms. A more drastic solution would be to also overwrite or hide
the current document pending page transition, or to perform onclick checks on all UI actions, and deny them from within frames. All of these mechanisms also fail if the user has JavaScript disabled globally, or for the attacked site. Likewise, because of the features of JavaScript, the following is enough to prevent frame busting in Microsoft Internet Explorer 7: <script> var location = "clobber"; </script> <iframe src="http://www.example.com/frame_busting_code.html"></iframe> Joseph Schorr cleverly pointed out that this behavior may be worked around by creating an <A HREF="..." TARGET="_top"> HTML tag, and then calling the click() on this element; on the other hand, flaws in SECURITY=RESTRICTED frames render even this variant of limited use. Relevant tests: Test description | MSIE6 | MSIE7 | MSIE8 | FF2 | FF3 | Safari | Opera | Chrome | Android | Is CSS opacity supported ("decoy underneath")? | YES | YES | YES | YES | YES | YES | YES | YES | YES | Are partly obstructed IFRAME containers clickable ("decoy on top")? | YES | YES |
| YES | YES | YES | YES | YES | YES | Is cross-domain scrollBy scrolling permitted? | NO | NO | NO | NO | NO | NO | NO | NO | n/a | Is cross-domain anchor-based frame positioning permitted? | YES | YES | YES | YES | YES | YES | YES | YES | n/a | Is X-Frame-Options defense available? | NO | NO | YES | NO | NO | YES | NO | YES | n/a |
|