LoginSignup
10
4
記事投稿キャンペーン 「Rails強化月間」

CookieのSameSite=Laxの動きを確かめるためにローカル開発環境をHTTPS化する

Posted at

要約

ローカル開発環境の https 化 | blog.jxck.io をやってみたら、思っていたより手軽だった話です。

現象

ある日、サイトAからサイトBに編集データを保存できなくなりました。
毎回サイトBでのログインが要求されます。一度ログインしても、サイドログインを求められます。
サイトBへの保存は、サイトAのJavaScriptでHTTPリクエストのPOSTメソッドを送っています。

ブラウザの開発ツールでみると、サイトBへのHTTPリクエストにCookieがついていません。

image.png

このため、サイトBではユーザーのログイン状態を確認できずログインを要求します。

原因の候補

最近のブラウザやWebアプリケーションフレームワークは、CookieのSameSite属性がLaxになっています123
これはサイトAのJavaScriptで作ったサイトB宛てのHTTPリクエストにサイトBのCookieをつけない制約です456
今回の事象にぴったりです。本現象の原因の候補です。
本当かどうか、実際に動かして確かめてみましょう。

命題

サイトBのCookieのSameSite属性をNoneに設定したときに、サイトAのJavaScriptで作ったHTTPリクエスト(特にPOSTメソッド)にサイトBのCookieをつけて送れるか確認します。

SameSite属性をNoneにするには、同時にSecure属性も設定する必要があります7
これは、HTTPSで接続したときのみCookieを送る設定です。
つまり、サイトBをHTTPSで動かす必要があります。

ローカル開発環境のHTTPS化

確認のためにHTTPS環境を用意したいです。
検証用にサーバーを用意するのは面倒です。
ローカル開発環境をHTTPS化します。

オレオレ証明書はつくりません。
ドメインを取得し、Let's Encryptから本物のSSL証明書を取得します。

環境

  • WSL + Ubuntu
  • Let's Encrypt
  • Rails 7.0.8
  • Puma

ドメインの取得

さくらインターネットで取得しました。
過去に取得したことがあるので、さくらインターネットを選びました。
どこで取得しても良いと思います。

Let's Encryptの認証にDNSをつかうので、DNSが設定できると便利だと思います。

取得したドメインに次のレコードを追加します。

名前
エントリ名 localhost
タイプ A
データ 127.0.0.1

例えばドメインがledsun.jp の場合に、ブラウザで http://localhost.ledsun.jp を開いた時に http://127.0.0.1 が開くようにします。

つづいて localhost.ledsun.jp のSSL証明書をLet's Encryptから取得します。

Certbotのインストール

Let's EncriptでSSL証明書するためにCertbotをインストールします8
Ubuntuではsnapdでインストール出来ます9

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

SSL証明書の取得

次のコマンドを実行します。

sudo certbot certonly --manual -d localhost.ledsun.jp --preferred-challenges dns

次のようなメッセージが表示されます。

Requesting a certificate for localhost3.ledsun.jp

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.localhost.ledsun.jp.

with the following value:

Ik9IyRLRei27lWszeyYyWJmCVA13kO_7LGOucXcSuEc

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.localhost3.ledsun.jp.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

このメッセージから上手いこと情報を読み取って、DNSに次のレコードを追加します。

名前
エントリ名 _acme-challenge.localhost
タイプ TXT
データ Ik9IyRLRei27lWszeyYyWJmCVA13kO_7LGOucXcSuEc

この値はこの記事を書くために生成してるので、この値をそのまま使っても特に得することはありません。

レコードを追加してから30分くらいまってEnterキーを押します。
レコードを追加した直後はDNSに反映されないらしく失敗します。
どれくらいまで良いのかはわかりません。とりあえず30分待てば大丈夫なようです。

成功すると /etc/letsencrypt/live/localhost.ledsun.jp 配下にSSL証明書が作成されます。

HTTPSでの起動

作成したSSL証明書をアプリケーションのディレクトリにコピーします。
root権限で作ったので、所有者を変更します。

sudo cp /etc/letsencrypt/live/localhost.ledsun.jp/privkey.pem .
sudo chown ledsun privkey.pem
sudo cp /etc/letsencrypt/live/localhost.ledsun.jp/fullchain.pem .
sudo chown ledsun fullchain.pem

config/puma.rbに証明書を設定します。

config/puma.rb
ssl_bind "0.0.0.0", "3001", {
  key: './privkey.pem',
  cert: './fullchain.pem'
}

bin/rails sでRailsアプリケーションを起動すれば、 https://localhost.ledsun.jp:3001/ で接続出来ます。

動作確認

Cookieの設定をSameSite=noneにして動作確認してみましょう。
config/application.rbに次の設定を追加します。

config/application.rb
config.action_dispatch.cookies_same_site_protection = :none
config.force_ssl = true
config.hosts << "localhost.ledsun.jp:3001"

bin/rails sでRailsアプリケーションを起動します。
このあとサイトAのアプリケーションからHTTPリクエストのPOSTメソッドを送ってCookieを送信できれば成功です。

  1. ブラウザの開発コンソールログを開く
  2. POSTメソッドを送る
  3. ネットワークタブで、送信したPOSTメソッドを選択
  4. Cookieタブを開く

image.png

Cookieが送信されていることがわかります。

SameSite=Laxのとき

比較用にSameSite=Laxのときの開発コンソールの表示を載せます。

image.png

「フィルターで除外された要求 Cookie を表示する」をチェックすると送れなかったCookieを確認できます。

image.png

SameSite属性がLaxであることがわかります。

まとめ

ローカル開発環境をHTTP化することで、SameSite=noneの動作を確認できました。
オレオレ証明書ではないので、ブラウザでの警告等はでません。
ドメインの取得費用は掛かりますが、1つあれば色々なアプリケーションで活用できます。
今後のWeb技術はHTTPSを前提とした物が増えると思います。
個人で1つ開発用のドメインを持っておくのも良いのかも知れません。

参考

  1. Chrome 80が密かに呼び寄せる地獄 ~ SameSite属性のデフォルト変更を調べてみた #Chrome - Qiita

  2. RailsでのCookieのSameSite, Secureの対応 #Ruby - Qiita

  3. SameSite=Lax is default value since Rails 6.1 · Issue #31 · pschinis/rails_same_site_cookie

  4. SameSite Cookie の説明  |  web.dev

  5. Cookie の性質を利用した攻撃と Same Site Cookie の効果 | blog.jxck.io

  6. Google Developers Japan: 新しい Cookie 設定 SameSite=None; Secure の準備を始めましょう

  7. Set-Cookie - HTTP | MDN

  8. Let's EncryptのSSL証明書をDNS認証で発行してみた。(DNSはお名前.com) #googlecloud - Qiita

  9. Install Let's Encrypt SSL on Ubuntu with Certbot | InMotion Hosting

10
4
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
10
4