3 ポイント 投稿者 GN⁺ 2024-11-22 | 1件のコメント | WhatsAppで共有
  • HTTPクッキー: Webの状態を維持するために使われる小さなデータ片で、ブラウザが設定した後、有効期限が切れるまで、すべてのHTTPリクエストに含まれる。
  • 問題の発生: 特定のJavaScriptコードにより、Go標準ライブラリでクッキーをパースできず、エラーが発生した。

仕様

  • RFC 2109, 2965, 6265: クッキーの初期定義と更新。クッキー値に関する仕様がサーバーとブラウザの間で一致していない。
  • 問題点:
    1. サーバーが送るべきものと、ブラウザが受け入れるべきものが一致していない。
    2. ブラウザがサーバーへ送るクッキー値に制限がない。
    3. 標準ライブラリがクッキーヘッダーを処理する方法について明確な指針がない。

Webブラウザ

  • Firefox: RFCで推奨されていないいくつかの文字を許可している。
  • Chromium: Firefoxよりやや制限的だが、それでも多くの文字を許可している。
  • Safari: 許可されていない文字に遭遇してもクッキー処理を中断せず、その文字までの値を受け入れる。

標準ライブラリ

  • Golang: RFCに近い動作をするが、空白とカンマを許可する。
  • PHP: 特定の制御文字でエラーが発生する。
  • Python: 理解できないクッキーを無視し、追加のクッキー読み込みを中断する。
  • Ruby: すべての文字を受け入れ、パーセントエンコーディングする。
  • Rust: すべてのUTF-8文字列を受け入れる。

Webにおける重要性

  • 現実の問題: 仕様の曖昧さにより、多くのWebサイトで簡単にエラーが発生しうる。
  • 解決策: IETF HTTP Working Group がクッキー仕様を更新し、ブラウザと言語がクッキーをどう処理すべきかを明確にする必要がある。

要約表

  • ブラウザと言語のクッキー処理: 各ブラウザと言語でクッキー処理の方法が異なり、RFCとの一致度も異なる。

1件のコメント

 
GN⁺ 2024-11-22
Hacker Newsの意見
  • Cookie には予期しない問題や扱いにくい挙動が含まれており、99.95% のケースでは動作する。Cookie シャドーイングは、同じ名前だが異なるキー属性(ドメイン、パスなど)を持つ Cookie を設定したときに発生する問題で、バックエンドや JS はどの Cookie なのか区別できない

  • Rust には標準ライブラリに Cookie 処理機能がなく、サードパーティの cookie クレートの挙動を参照している。これは Ruby と同様にパーセントエンコーディングのオプションを含む

  • HTTP プロトコルは数多くの別のプロトコルを内包しており、ブラウザと Web サーバーはさまざまな機能を追加している。こうした機能には明確な仕様がなく、クライアントとサーバーが互換性を指定することもできない。そのため、過去の誤った判断を引きずり続ける状況になっている

  • 約 10 年前、プロジェクトで Cookie ベースのセッションを実装したとき、Safari では動作するのに Chrome では動作しない問題に遭遇した。これは、正しい形式でなければブラウザが Cookie を設定しないという違いが原因だった

  • Cookie の唯一合理的な用途は、サーバーがクライアントを認識できるように不透明なトークンを設定することだ。クライアントが、サーバーが送らない値を処理できること自体は問題ではない

  • Cookie は複雑な問題であり、下位互換性の問題のため変更はほとんど不可能だ。新しいメカニズムを作る必要がある。たとえば NewCookie メカニズムなら、現代的なセキュリティ対策と厳格な仕様を備えられる

  • Cookie は消えるべきで、認証ヘッダーに置き換えられるはずだ。ブラウザから Web サイトに標準的な方法で認証できればよいのにと思う。Basic 認証や Digest 認証が十分ではなかったのは残念だ

  • Safari のネットワーキングコードはオープンソースではないため、Swift の Foundation ポートが良い代替になるかもしれない。そこで制御文字や削除文字を確認できる

  • Cookie ヘッダーのパースは混乱を招く。「標準」は実際に存在するものを反映しておらず、各バックエンドサーバー、ライブラリ、フレームワークはそれぞれ異なるものを受け入れている。フロントエンドとバックエンドを完全に制御できるなら大きな問題ではないが、他のものと相互作用しなければならないと非常に複雑になる

  • Crystal 言語で実験していたときにも似た問題を経験した。簡単な Web スクレイパーを構築しようとしたが、デフォルトの HTTP クライアントがレスポンスで設定された多くの Cookie をパースできず停止してしまった