Laravel の脆弱性 CVE-2017-14775 の対処法

こんにちは。エンジニアの @localdisk です。2017/09/27に CVE-2017-14775 という Laravel の脆弱性が報告されました。CVE-2017-14775 はオートログイン処理に*1タイミング攻撃の脆弱性があるというものです。

タイミング攻撃についてとその対策については下記エントリに詳しくまとまっています。

この脆弱性は 2017/09/21 にリリースされた 5.5.10 で修正されています。対象のクラスは下記になります。

  • Illuminate\Auth\DatabaseUserProvider
  • Illuminate\Auth\EloquentUserProvider

修正された PR は下記になります。

以前は remember_token を DB の where 条件としていますがこの修正ではプライマリキーでモデルを取得し remember_token カラムの値と引数を hash_equals 関数で比較しています。

この hash_equals 関数がポイントでこの関数はタイミング攻撃の対策となります。

即座にバージョンアップできないあなたへ

さて、5.5 をお使いの人は composer update すれば万事解決なのですが、5.5 未満のバージョンを使っている場合はそうもいきません。現在の LTS は 5.5 であり、それ未満のバージョンを使っている場合は自力で対処するしかありません。なのでやっていきましょう💪

カスタムプロバイダへの差し替え

(2017/10/17 追記) EloquentUserProvider, DatabaseUserProvider の修正は大体一緒なので本エントリでは EloquentUserProvider の差し替え方を説明します。

CVE-2017-14775の脆弱性で修正が必要なのは下記のクラスの retrieveByToken メソッドです。

  • Illuminate\Auth\DatabaseUserProvider
  • Illuminate\Auth\EloquentUserProvider

config/auth.php の下記でどの Provider を使用しているかがわかります。

<?php
return [
'providers' => [
    'users' => [
        'driver' => 'eloquent', // ここ。デフォルトは eloquent
        'model' => App\User::class,
    ],
];

drivereloquent の場合は EloquentUserProviderdatabase の場合は DatabaseUserProvider が差し替えの対象になります。

まずは差し替える カスタムプロバイダ を作成しましょう。 app ディレクトリの下に Auth ディレクトリを作成し、下記 CustomEloquentUserProvider を作成しました。

<?php

namespace App\Auth;

use Illuminate\Auth\EloquentUserProvider;

class CustomEloquentUserProvider extends EloquentUserProvider
{

    /**
     * Retrieve a user by their unique identifier and "remember me" token.
     *
     * @param  mixed $identifier
     * @param  string $token
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByToken($identifier, $token)
    {
        $model = $this->createModel();

        $model = $model->where($model->getAuthIdentifierName(), $identifier)->first();

        if (!$model) {
            return null;
        }

        $rememberToken = $model->getRememberToken();

        return $rememberToken && hash_equals($rememberToken, $token) ? $model : null;
    }
}

retrieveByToken メソッドは修正された内容を反映したものをそのままコピーしています。次は \App\Providers\AuthServiceProviderboot メソッドに下記内容を追加します。

<?php
class AuthServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // custom という名前で カスタムプロバイダ を登録
        Auth::provider('custom', function ($app, array $config) {
            return new CustomEloquentUserProvider($app['hash'], $config['model']);
        });
    }
}

最後に config/auth.php を変更します。カスタムプロバイダ を指定して終了。簡単ですね。

<?php
return [
'providers' => [
    'users' => [
        'driver' => 'custom', // eloquent から custom に変更
        'model' => App\User::class,
    ],
];

まとめ

今回はバージョンアップする工数はすぐには確保できない方に向けてエントリを書きましたが、一番の対策はこまめなバージョンアップです。Laravel AnnouncementsLaravel News 等、便利な情報源がありますので上手く活用していきましょう。

*1:Remember me のアレ

Supervisorのインストールで起動スクリプトを書きたくなかったのでRPMから抽出して利用した話

f:id:akase244:20170928112758j:plain

こんにちは、エンジニアの @akase244 です。

プロセス管理ツールのSupervisorをAmazon Linux(version 2017.03)上にインストールする機会があったので、その際のインストールメモをザザッとまとめました。

続きを読む

Nginx Unit で Laravelを動かしてみた

f:id:hanhan1978:20170914162426p:plain

こんにちはエンジニアの @hanhan1978 です。2017年9月6日にNginxがApplication Platformの「Unit」をリリースしました。 Introducing the NGINX Application Platform with Controller and Unit

世界中がザワザワしているようですが、特に日本はザワザワしているようで、Google Trendで調べて見たら日本が一番バズってます。 Nginx Unit - Google トレンド

PHP界隈でも、PHP-FPMに取って代わる&HTTPで通信できるモダンなアプリケーションサーバがついに登場か!?ということでザワザワしています。 自分も、Dockerコンテナ上でPHPアプリケーションを動かす最適解を勝手に探し求めている人間なので、もしかして「Unit」はPHPアプリケーションのコンテナ化を促す強い推進力になるかもとウキウキしてしまいました。

というわけで、「Unit」でひとまずLaravelのアプリケーションを動かしてみて、どんな構成で動かせばいいのか調べてみました。

続きを読む

AWS Simple Email Service(SES)のConfiguration Setでメール開封とクリックを計測できるようにしてみた。

f:id:gurimmer:20170831125142j:plain Photo by Kirsty TG on Unsplash

こんにちは、@gorouです。 8月始めごろ、AWSのSimple Email Service(以下、SES)で送信したメールの開封・クリック計測ができるConfiguration Set機能のリリースが発表されました。

Amazon SES で顧客エンゲージメントを追跡するためのオープンおよびクリックメトリクスを導入

tenpuで実験的に実装を行ってみたので、機能の詳細を紹介します。

www.tenpu.me

続きを読む