様々な環境下でCookieをSameSite=None; Secureに設定して従来通りの挙動に変更する

様々な環境下でCookieをSameSite=None; Secureに設定して従来通りの挙動に変更する

2020年2月17日の週から、限られた初期人口向けのChrome 80 StableよりSame-Site属性のデフォルト値がNoneからLaxに変更されます。

Same-Site属性がLAXになると、他のサイトにGETメソッド以外を送信する際にCookieが送信されなくなります。

これはCSRF対策となり悪意のあるサイトから不正な操作を防ぐ事ができます。

しかし、これは喜ばしいことだけでは有りません。

クレジットカード決済代行サービスなどの悪意のないサイトからの通信時でもCookieが送信されなくなってしまいます。

Cookieが送信されないとステートレスなHTTP通信だけでは、セッションIDなどでのユーザーの識別を行うことができません。

これによりECサイトではクレジット決済時不具合が発生致します。

他にも他のサービスと連携しているサイトなどでは不具合が発生する可能性があります。

対策

従来通りの動きにするためは、CookieにSameSite=Noneを付けた上でSecure属性を付与する必要性があります。

Apacheの場合

Apacheは.htaccessでCookieにデフォルトの属性を追加することができます。

<ifmodule mod_headers.c>
Header always edit Set-Cookie (.*) "$1; secure; SameSite=none"
</ifmodule>

Nginxの場合

Nginxではproxy.confでCookieにデフォルトの属性を追加することができます。

proxy_cookie_path / "/; secure; SameSite=none";

PHP7.3+の場合

セッションのみ

Same-Site属性はPHP7.3で新規に追加されました。したがってPHP7.3以上のバージョンではsession_set_cookie_paramsを使用することでセッションにSame-Site属性を付与することができます。

<?php
$cookieParams = session_get_cookie_params();
$cookieParams[samesite] = "None";
session_set_cookie_params($cookieParams);

session_start();

または、php.iniに以下の設定を追加することでもSame-Site属性を付与することができます。

session.cookie_samesite=None

Cookieすべて

<?php
setcookie('cross-site-cookie', 'name', ['samesite' => 'None', 'secure' => true]);

PHP7.2以下の場合

<?php
header('Set-Cookie: cross-site-cookie=name; SameSite=None; Secure');

Laravel5.5+の場合

Laravel5.5+ではconfig/session.phpでSame-Site属性を設定することができます。

'same_site' => 'none',

Symfony 4.3.6+の場合

Symfony 4.3.6以降、samesite: ‘none’がサポートされています。

自動ログインの設定

# config/packages/security.yaml
security:
    # ...

    firewalls:
        main:
            # ...
            remember_me:
                # ...

                # possible values: 'strict', 'lax' and null
                samesite: 'none'

セッションの設定

# config/packages/framework.yaml
framework:
    # ...
    session:
        # ...
        cookie_samesite: 'none'

Django 2の場合

Django 2では、django-cookies-samesiteを使用するのが比較的簡単かと思います。

インストール

$ pip install django-cookies-samesite

ミドルウェアの追加

# settings.py
MIDDLEWARE_CLASSES = (
    'django_cookies_samesite.middleware.CookiesSameSite',
    ...
)

Same-Site属性の変更

# settings.py
SESSION_COOKIE_SAMESITE = 'None'

Cookie名の変更

# settings.py
SESSION_COOKIE_SAMESITE_KEYS = {'my-custom-cookies'}

参考サイト