5

My website offers rich content to users. I often subscribe to third party vendors whose content I embed in my pages. How can I safely embed external domain's content on my webpage in an iframe without worrying that they won't be able to bust out of frame. They won't do it purposely (without risking their clientage/reputation). However, since they almost always are small shops, they become a juicy targets for an attacker who wants to deface/redirect my website.

Is there a header (something similar/opposite to X-Frame-Options) which I can use on my parent page to ensure that the iframes I embed can't bust out? Remember, I can't ask vendors to add headers/scripts to their pages. They never purposely want to do nefarious things to my page. The scenario I am trying to cover is the one when they get hacked.

6

You need the sandbox attribute. This is a new attribute supported by all major browsers. Sandbox attribute imposes extra restrictions on the content inside the iframe - one of those restrictions is running javascript. You can choose to remove the other restrictions that you do not want to impose.

Use the following to embed URLs from different/untrusted domains in your web pages:

<iframe src="http://example.com/external-content.htm" sandbox></iframe>

Here is the quick reference (copied from the w3schools link above):

When the sandbox attribute is present, and it will:

  • treat the content as being from a unique origin
  • block form submission
  • block script execution
  • disable APIs
  • prevent links from targeting other browsing contexts
  • prevent content from using plugins (through , , , or other)
  • prevent the content to navigate its top-level browsing context (this is what you need)
  • block automatically triggered features (such as automatically playing a video or automatically focusing a form control)
  • This works for what I am trying to achieve. Thanks! – Naya Bonbo Oct 24 '15 at 19:54
  • Good solution. I didn't realize they added that in HTML5. @NayaBonbo, seeing as you're framing content from small shops, you might consider enabling things like script execution, APIs, and forms (otherwise you might unintentionally make the framed website inoperable). Based on the W3Schools link CodeExpress provided, you could should be able to say sandbox="allow-forms allow-pointer-lock allow-scripts". – Spencer D Oct 24 '15 at 20:13
2

After a quick search, I found the following two relevant StackOverflow (SO) questions about this:

  1. Preventing child iframe from “breaking out of frame”; and
  2. Frame Buster Buster … buster code needed

These questions are a bit dated, but they suggest applying the following code to prevent parent (top) redirects:

<script type="text/javascript">
    var prevent_bust = 0;
    window.onbeforeunload = function() { prevent_bust++; }
    setInterval(function() {
      if (prevent_bust > 0) {
        prevent_bust -= 2;
        window.top.location = 'http://example.org/page-which-responds-with-204';
        /* Replace URL with a page that actually responds with HTTP status code 204 */
      }
    }, 1);
</script>

Basically this snippet of JavaScript will stop the iframed page from making changes to top.location; thus, this code prevents the iframe from redirecting.

The second SO question was the original source for this code, but that question was asking for a way to bust this iframe-buster busting code. (In other words, SO source #2 was looking for a way to bypass this code that prevents iframe redirects.) However, it doesn't seem like a viable solution was presented to get around this anti-redirect code. So, this appears to be a fairly safe solution.

Of course, anytime you include an iframe or other code from another website/server, you inherit some risks by doing such. However, this should be a viable solution to mitigate that risk.

  • 1
    This might work, however running a javascript function every millisecond is a deal breaker. My users will hate me for doing that to their browsers. On a side note: setTimeout() should always be preferred over setInterval() to call a function in a loop. setInterval will call a new instance even if the old instance's execution hasn't finished (which is likely if you are executing a function every millisecond) - which in turn will hog the resources and might make the webpage unresponsive. – Naya Bonbo Oct 24 '15 at 19:52
  • @NayaBonbo, the code is just a direct copy and paste from the linked SO questions with only some minor changes to the syntax. That said, yes, running a function every millisecond would be performance heavy and setTimeout would most likely be more resource friendly. One could probably safely change this to a timeout with a higher interval, but since I'm not familiar with code nor have I tested it myself, I didn't feel like it was my place to make that modification. All of that said, the sandbox attribute seems like a much cleaner solution. I wasn't aware that was added in HTML5. – Spencer D Oct 24 '15 at 20:05
  • +1 I understand, your answer does provide an interesting theoretical solution though. I am sure one can vet it to make it more practical. Thanks for taking the time to do the research. – Naya Bonbo Oct 24 '15 at 20:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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