LoginSignup
20
15

More than 5 years have passed since last update.

Laravelセキュリティ:クリックジャッキング対策

Posted at

結論

適当なミドルウェアを作成してhandleを以下のようにした後、webのミドルウェアグループに追加する。

$response = $next($request);
//$response->header('X-Frame-Options', 'deny');ではだめ(後述)
$response->headers->set('X-Frame-Options', 'deny'); //状況に応じてsameoriginやallow-fromを指定
return $response;

クリックジャッキングとは

攻撃者が作成したページの上に透過iframeなどでターゲットのwebサイトを埋め込み、ユーザーに対してターゲットのwebサイト上で何かしらのアクションをさせる攻撃のこと。下の図で言えばユーザーからはピンクのページしか見えておらず、指示通りに「ココをクリック」の場所を押したつもりが、実際にはサイトAで情報公開を選択してしまったことになる。

image.png

画像:IPA 「知らぬ間にプライバシー情報の非公開設定を公開設定に変更されてしまうなどの『クリックジャッキング』に関するレポート」(https://www.ipa.go.jp/files/000026479.pdf) より

Laravelではこれを防ぐような仕組みが組み込まれていないので、自分でなんとかしましょうという記事です。

クリックジャッキングを防ぐには

上の説明から分かるように、自分のwebサイトがiframeやembedなどで埋め込まれるとまずいわけです。よってこれを回避しましょうという話なのですが、最近のブラウザではレスポンスヘッダに「X-Frame-Options」を指定することで埋め込みを許可する、しないを制御することができます。

参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options

レスポンスヘッダにこのオプションを指定するため、LaravelではMiddlewareを利用するのが良さそうです。

$ php artisan make:middleware AddXFrameOptions
AddXFrameOptions.php
<?php

namespace App\Http\Middleware;

use Closure;

class AddXFrameOptions
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $response->headers->set('X-Frame-Options', 'deny'); //状況に応じてsameoriginやallow-fromを指定
        return $response;
    }
}

APIは関係ないのでwebグループの方に先ほどのミドルウェアを追加します。

Kernel.php
protected $middlewareGroups = [
        'web' => [
            ...
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\AddXFrameOptions::class // 追加
        ],
...
];

curlなどでレスポンスヘッダにX-Frame-Optionsが追加されていることを確認しましょう。

$ curl -D - http://localhost/myapp

おまけ

冒頭にあるように、ミドルウェアでヘッダーを追加する際、

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

としてしまうと、ダウンロード等でファイルを返す際に以下のようなエラーが出ます。

Call to undefined method Symfony\Component\HttpFoundation\BinaryFileResponse::header()

https://stackoverflow.com/questions/29289177/binaryfileresponse-in-laravel-undefined にあるように、header()はSymfonyのResponseには定義されていないからだそうです。ややこしや。

20
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
15