I did a small test on Chrome (V37) today. I created a small page and loaded it to the browser:

<!DOCTYPE html>
<html>
<head>
    <title>Untitled Document</title>
</head>
<body>
    <p>Normal page</p>
    <iframe src="https://security.stackexchange.com/" />
</body>
</html>

Inspecting the console I found this error message:

Refused to display 'https://security.stackexchange.com/' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.

Why do browsers need to enforce same-origin policy on iframes?

  • Short answer: Because, in this instance, Stack Exchange explicitly asked it to. "it set 'X-Frame-Options' to 'SAMEORIGIN'" – Ajedi32 Jul 16 '15 at 16:55
up vote 39 down vote accepted

Review: Same-origin policy

First, let's clarify that the behavior observed here (the iframe does not render) is much stricter than the default same-origin policy. If you already understand that, skip down to "What's actually happening," below.

To review, the same-origin policy prevents scripts from having programmatic access to the contents of cross-origin resources. Consider how the same-origin policy applies to various types of resources:

  • Images: An <img> tag will show a cross-origin image to a user visually, but it will not allow a script to read the image content when loaded into a <canvas> (i.e., toDataURL will fail if the canvas contains any cross-origin images)
  • Scripts: Cross-origin scripts will run when referenced in a <script> element, but the page can only run the script, not read its contents.
  • Iframe: Like images, the contents of a framed cross-origin page appear visually to the user, but scripts in the outer framing page are not allowed access to the framed page's contents.

The same-origin policy applies to iframes for the same reason it applies to all other types of resources: the web page being framed (or the image being displayed, or the resource being accessed via Ajax) is fetched using credentials from the resource's own origin (e.g., the HTTP request to fetch a resource from google.com includes my browser's cookies set for google.com). The page that issued the request should not be given read-access to a resource fetched with credentials from a different origin.

What's actually happening: X-Frame-Options

However, the behavior you see here is stricter than the same-origin policy: the framed page is not shown at all. The cross-origin server that hosts the (would-be) framed page requests this blocking behavior by sending an X-Frame-Options response header, which specifies how the page is allowed to be framed.

  • DENY The page cannot be displayed in a frame, regardless of the site attempting to do so.
  • SAMEORIGIN The page can only be displayed in a frame on the same origin as the page itself.
  • ALLOW-FROM uri The page can only be displayed in a frame on the specified origin.

Here, the site sends X-Frame-Options: SAMEORIGIN, which means the site can only be framed by pages with the same origin as the framed page.

From a security standpoint, this is done to prevent clickjacking (also called a "UI redress" attack). In a clickjacking attack, the page displays a click-activated component of another site inside an <iframe> and tricks the user into clicking it (usually by layering the the target component on top of an apparently-clickable feature of the framing site).

For a trivial example, a site might position a transparent <iframe> of http://security.stackexchange.com so that the "log out" link in the framed site was directly over top of a "Click here to claim your free money" button. When viewing the framing page, the user attempts to claim the free money, and suddenly finds himself logged out of Stack Exchange. When http://security.stackexchange.com sends an X-Frame-Options: SAMEORIGIN header, the malicious cross-origin page gets only an empty <iframe> instead; the user doesn't unwittingly click a log-out link because no content from the framed site made it onto the rendered page.

OWASP has a page detailing defenses against clickjacking.

The administrators of security.stackexchange.com have configured the site to not let it be framed on other sites. This is usually done to prevent clickjacking attacks, to prevent others from embedding security.stackexchange.com into a page full of ads, and to save traffic. You may read more about X-Frame-Options header here.

This protection is off by default.

  • 8
    for more information on click-jacking attacks, check troyhunt.com/2013/05/… – Nzall Sep 22 '14 at 8:02
  • 31
    I'm not clicking that @Nate – Krumia Sep 22 '14 at 8:58
  • 1
    @Krumia Your loss. Troy Hunt is one of the major advocates of web security, though. If you don't believe me on my word, I understand that. You can use websites like scanurl.net or norton safe web to validate the link for yourself. – Nzall Sep 22 '14 at 9:03
  • 23
    @NateKerkhofs: It was a joke, since we were talking about internet security and especially about "clickjacking". I read the link nevertheless. :D Interesting read. – Krumia Sep 22 '14 at 9:12
  • 7
    @algiogia That's not the same thing. Try this: en.wikipedia.org/wiki/Clickjacking – ntoskrnl Sep 22 '14 at 14:56

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.