hanami にセッション管理を導入しようとしている。デフォルトでは Rack::Session::Cookie を使って cookie にセッションキーを格納する ことになっている。ちょうど先日、 Real World HTTP を読んで  cookie の仕組みを復習したところだったので、 Rack がそれをどう実装しているかに興味がわき、ソースを読んでみた。

 で、みていると、 httpOnly 属性はデフォルトでついている。 secure 属性はついていない。

rack/rack (https://github.com/rack/rack/blob/v2.2.2/lib/rack/session/abstract/id.rb#L239-L240)

 あれっ、と思いつつ、それぞれどのような棲み分けをしているのか理解が曖昧だったので、調べ直してみる。

Session Management (https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#cookies) Using HTTP cookies (https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)

 短くまとめると、

  1. httpOnly は document.cookie による読み出しを禁止する属性
  2. Secure は SSL/TLS 化された通信以外での送信を禁止する属性

ということだ。

 後者については、仮にウェブサイトを全面的に HTTPS 化していたとしても、さらにポート80を閉鎖していたとしても、Cookie に Secure 属性を指定しない限り、中間者攻撃で盗聴される可能性は存在するとのこと。

 Secure 属性がなければ、ウェブサイトの管理者がいくら HTTPS 通信を徹底したところで、ユーザーが HTTP リンクを踏まされてしまえば、 Cookie は通信経路上に露呈させられうる、ということ。そう解釈している。

 開発環境では http 接続を利用することが多いだろうから、対処するとすれば環境ごとに条件分けして付与するのが手間はかからないだろう。 Hanami であれば apps/web/application.rb にこう指定する。

module Web
  class Application < Hanami::Application
    configure do
      # ...
      # Enable sessions
      # Argument: Symbol the Rack session adapter
      #           A Hash with options
      #
      # See: http://www.rubydoc.info/gems/rack/Rack/Session/Cookie
      #
      sessions :cookie,
        secret: ENV['WEB_SESSIONS_SECRET'],
        secure: Hanami.env == 'production'
      # ...
    end
  end
end

 正直このあたりの細かな振る舞いは、いつも gem に任せていて仕様をよく把握できていなかったと反省している。一方で、Real World HTTP を読んだおかげで前提知識がインプットできたのか、このレイヤの話題がだんだんわかるようになりはじめて面白い。

『Real World HTTP 第2版』でHTTPの歴史的文脈と最新動向を俯瞰する - ユユユユユ (https://jnsato.hateblo.jp/entry/2020/05/18/140000)

 サービスを素早く立ち上げる、という観点では必ずしも優先度の高くない知識分野かもしれない。けれど、倫理的なサービス提供者としてユーザーへの責任を果たす、という意味では、決して軽んじられるべき技術ではない。