Laravel 4.1.x – Blank iframe – default X-Frame-Option header set to SAMEORIGIN – Fix (Facebook Page App Tab)

Laravel 4.1.x – Blank iframe – default X-Frame-Option header set to SAMEORIGIN – Fix (Facebook Page App Tab)
Rate This Post

Have you ever experienced a blank page/frame when embedding a Laravel app in an iframe (e.g. Facebook Application in a Page Tab)?

I ran into this subtle issue when I was making a Facebook Page Tab Application that embeds an app (using Laravel 4.1.x as the framework) in an iframe. I was able to troubleshoot this issue further by using Firebug/Google Dev tools to point me in the right direction. In:

  • Chrome Dev Tools: I was getting an error of “Refused to display ‘https://xxxx.xxx’ in a frame because it set ‘X-Frame-Options’ to ‘SAMEORIGIN'”
    chrome_xframe
  • Firebug: I was getting an error of “Load denied by X-Frame-Options: https://xxxx.xxx does not permit cross-origin framing.”
    firefox_xframe

It turns out in Laravel 4.1.x, by default there is something called the “FrameGuard” that sets the X-Frame-Option in the HTTP headers to SAMEORIGIN, which means page can only be displayed in a iframe from the same origin (the domain itself). This is a security feature added that was intended to preventclickjacking.”

There is a discussion thread outlining the addition and proposed implementation on github (see references). In 4.1.x it was deemed fine to be activated “out-of-box”; however, in retrospect many issues have been raised by users and it will be disabled by default in Laravel version 4.2.

For users who are still using Laravel 4.1.x and want to disable the FrameGuard, all you need to do is edit the start.php file in the “bootstrap” folder and add the following line before the return statement.

  • App::forgetMiddleware(‘Illuminate\Http\FrameGuard’);

So for example in my start.php, I have (notice before the “return $app;”):

  1. require $framework.'/Illuminate/Foundation/start.php';
  2.  
  3. /*
  4. |--------------------------------------------------------------------------
  5. | Return The Application
  6. |--------------------------------------------------------------------------
  7. |
  8. | This script returns the application instance. The instance is given to
  9. | the calling script so we can separate the building of the instances
  10. | from the actual running of the application and sending responses.
  11. |
  12. */
  13.  
  14. App::forgetMiddleware('Illuminate\Http\FrameGuard');
  15.  
  16. return $app;

This will remove the FrameGuard and allow users to use Laravel in an iframe (that is of different origin). Or in my case, allow my Facebook app to be embedded within an iframe in my Facebook Page Tab.

I can see how this issue could be frustrating to many developers as the error is not particularly overt, nor is this type of Framework change particularly clear or obvious in any way.

Reference: https://github.com/laravel/framework/issues/1725 and https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options