対応しきれてるか自身ないけど、多分コレで大丈夫なはず。自己責任でおなしゃす。間違いあったら教えてくださいまし。
参考
作業見立て
\Illuminate\Auth\EloquentUserProvider
と \Illuminate\Auth\DatabaseUserProvider
にある remember_token
のチェックを hash_equals
関数をかましてやる。ただその二つは Laravel5.1 では \Illuminate\Auth\AuthManager
にベタ書きで使われているので、設定で変更して対処することはできない。
\Illuminate\Auth\AuthManager
は\Illuminate\Auth\AuthServiceProvider
でしか使われていないので、\Illuminate\Auth\AuthServiceProvider
の部分から書き換えていく必要がある。ただこの部分、全文検索とかで調べた程度なのでほんとうに大丈夫かちょっと不安。
とりあえずで変更していく。
変更箇所
- config/app.php
- \Illuminate\Auth\AuthServiceProvider
- \Illuminate\Auth\AuthManager
- \Illuminate\Auth\DatabaseUserProvider
- \Illuminate\Auth\EloquentUserProvider
それぞれ継承して、プロジェクトディレクトリに置いて対応。 app.php
は一行だけ置き換えが必要。
EloquentUserProvider
<?php
namespace App\Providers;
class EloquentUserProvider extends \Illuminate\Auth\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;
}
}
DatabaseUserProvider
<?php
namespace App\Providers;
class DatabaseUserProvider extends \Illuminate\Auth\DatabaseUserProvider
{
/**
* 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)
{
$user = $this->conn->table($this->table)
->where('id', $identifier)
->first();
return $user && hash_equals($user->remember_token, $token) ? $this->getGenericUser($user) : null;
}
}
AuthManager
app/Lib/Auth
ディレクトリは標準では存在しないが、自己都合の為に作っている。
<?php
namespace App\Lib\Auth;
use App\Providers\DatabaseUserProvider;
use App\Providers\EloquentUserProvider;
/**
* Class AuthManager
* @package App\Lib\Auth
*/
class AuthManager extends \Illuminate\Auth\AuthManager
{
/**
* Create an instance of the database user provider.
*
* @return \Illuminate\Auth\DatabaseUserProvider
*/
protected function createDatabaseProvider()
{
$connection = $this->app[ 'db' ]->connection();
// When using the basic database user provider, we need to inject the table we
// want to use, since this is not an Eloquent model we will have no way to
// know without telling the provider, so we'll inject the config value.
$table = $this->app[ 'config' ][ 'auth.table' ];
return new DatabaseUserProvider( $connection, $this->app[ 'hash' ], $table );
}
/**
* Create an instance of the Eloquent user provider.
*
* @return \Illuminate\Auth\EloquentUserProvider
*/
protected function createEloquentProvider()
{
$model = $this->app[ 'config' ][ 'auth.model' ];
return new EloquentUserProvider( $this->app[ 'hash' ], $model );
}
}
AuthServiceProvider
<?php
namespace App\Providers;
use App\Lib\Auth\AuthManager;
/**
* Class AuthServiceProvider
* @package App\Providers
*/
class AuthServiceProvider extends \Illuminate\Auth\AuthServiceProvider
{
/**
* Register the authenticator services.
*
* @return void
*/
protected function registerAuthenticator()
{
$this->app->singleton( 'auth', function ($app){
// Once the authentication service has actually been requested by the developer
// we will set a variable in the application indicating such. This helps us
// know that we need to set any queued cookies in the after event later.
$app[ 'auth.loaded' ] = true;
\Log::debug( 'CVE-2017-14775 check.', [ 'file' => __FILE__, 'line' => __LINE__ ] );
return new AuthManager( $app );
} );
$this->app->singleton( 'auth.driver', function ($app){
return $app[ 'auth' ]->driver();
} );
}
}
config/app.php
全部は出せないので、変更箇所だけ。
要は providers
にあるIlluminate\Auth\AuthServiceProvider
をApp\Providers\AuthServiceProvider
にすれば良い
<?php
return [
'providers' => [
'App\Providers\AuthServiceProvider',
// 'Illuminate\Auth\AuthServiceProvider',
];
他のバージョンは
5.2,5.3,5.4 系なら Laravel の脆弱性 CVE-2017-14775 の対処法 で対応可能なはずです。
5.0,5.1系はこの方法になるかな…