En cliquant sur "Accepter", vous acceptez que des cookies soient stockés sur votre appareil afin d'améliorer la navigation sur le site. Consultez notre politique de confidentialité pour plus d'informations.
Home
/
Blog
/
Article

Cross-origin iFrames avec Laravel

Publié le
16 Septembre 2018
-
2 min
de lecture

Partager l'article

Peut-être avez-vous déjà rencontré l'une de ces erreurs lors de la création d'une page pouvant être intégrée dans un iFrame:

  • Blocked a frame with origin ... from accessing a frame with origin ...
  • Unsafe JavaScript attempt to access frame with URL ...
  • Invalid 'X-Frame-Options' header encountered when loading ...

Elles sont dues aux navigateurs empêchant l’incorporation ou l’accès à un iFrame à partir d’un domaine non autorisé.

La solution présentée dans cet article suppose que vous ayez accès au serveur et à l'application hébergeant le contenu de cet iFrame.

Il s’agit d’une application Laravel hébergée sur Laravel Forge, mais applicable à la plupart des applications Web exécutées sur Nginx ou Apache.

Modifier la configuration du serveur

Premièrement, nous devons vérifier que la configuration de notre serveur ne contient pas d’en-têtes empêchant l’incorporation des pages dans un iFrame.

La configuration par défaut de Nginx lorsqu'un nouveau site est provisionné par Laravel Forge contient un paramètre X-Frame-Options que nous allons supprimer, afin que nous puissions contrôler cet en-tête HTTP dans notre application.

Dans Laravel Forge, allez sur Sites, puis dans l'ongletApps, faites défiler vers le bas de la page.

Cliquez ensuite sur Edit Nginx Configuration et commentez cette ligne:


# add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

Ensuite, vous pouvez enregistrer la configuration et redémarrer Nginx.

Sur Apache, la configuration serait du genre "Header always append X-Frame-Options SAMEORIGIN""

Créer un Middleware

Maintenant que nous avons supprimé cet en-tête de la configuration du serveur, nous allons créer un middleware qui nous permet de le contrôler.

Pour cela, vous pouvez exécuter la commande suivante pour créer un nouveau middleware appelé XFrameOptions:


$ php artisan make:middleware XFrameOptions

Et copier ce code à l'intérieur:


namespace App\Http\Middleware;

use Closure;

class XFrameOptions
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        $option = 'SAMEORIGIN';

        // In this example, we are only allowing the third party to include the "iframe" route
        // It's always better to scope this to a given route / set of routes to avoid any unattended security problems
        if ($request->routeIs('iframe') && $xframeOptions = env('X_FRAME_OPTIONS', 'SAMEORIGIN')) {
            if (false !== strpos($xframeOptions, 'ALLOW-FROM')) {
                $url = trim(str_replace('ALLOW-FROM', '', $xframeOptions));

                $response->header('Content-Security-Policy', 'frame-ancestors '.$url);
            }
        }

        $response->header('X-Frame-Options', $xframeOptions);
    }
}

Nous définissons les deux en-têtes X-Frame-Options etContent-Security-Policy, car X-Frame-Options est ignoré si CSP frame-ancestors est spécifié, mais Chrome 40 et Firefox 35 ignorent la directive frame-ancestors et prenent en compte X-Frame-Options à la place.

Seule la route iframe a été autorisée dans cet exemple. Autoriser l'intégration de toutes les routes de votre application dans des iFrames peut représenter un gros risque de sécurité.

Plus d'informations sur les risques de sécurité associés à cela peuvent être trouvées ici.

Vous pouvez maintenant éditer votre fichier .env afin de configurer X-Frame-Options pour chaque site autorisé, sans avoir à redémarrer le serveur web:


// .env

X_FRAME_OPTIONS=DENY
X_FRAME_OPTIONS="ALLOW-FROM https://google.fr"

C'est tout! Votre page peut maintenant être intégrée en tant qu'iFrame sur les sites autorisés dans la configuration :)

Revenir au blog