Cookieの安全性を高める "__HttpOnly-"プレフィックスの提案仕様

新しくCookieに"__HttpOnly-"プレフィックスを追加する『HttpOnly cookie prefix』という提案仕様が出されています。

Cookieには『Cookie Name Prefixes』という仕様があります(もうそろそろRFCになります)。なお、すでにブラウザに実装されています。

Cookie名にプレフィックスをつけることで、特定の属性が付与されている事が保証されます。

例えばCookie名に "__Secure-" をつけることで、secure属性が付与されている事が保証されます。javascriptや共有先のサイトにより勝手に属性値が外されることはありません。

現在は次の2つのプレフィックスが定義されています

  • __Secure-
  • __Host-

googleのサイトもすでに、これらがついたCookieを払い出しています

HttpOnly cookie prefix』では、新しく "__HttpOnly-", "__HostHttpOnly-"プレフィックス を定義します。

__HttpOnly- プレフィックス

このプレフィックスがついたCookie

  • HttpOnly 属性がついてる必要がある
  • Secure 属性がついてる必要がある

Set-Cookie: __HttpOnly-SID=31d4d96e407aad42;  Secure; HttpOnly

そうでない場合は、そのCookieは拒否されます

__HostHttpOnly- プレフィックス

このプレフィックスがついたCookie

  • HttpOnly 属性がついてる必要がある
  • Secure 属性がついてる必要がある
  • Path 属性の値が "/" である必要がある
  • Domain 属性が設定されていてはいけない

そうでない場合は、そのCookieは拒否されます

Cookieを消す Delete-Cookie ヘッダの議論

IETF HTTP WGでCookieを消去するレスポンスヘッダ『Delete-Cookie』の議論が行われています。

正式に提出されたものではありませんが、著者のYoav Weiss氏が個人リポジトリでDraftを公開しています。

yoavweiss.github.io

Delete-Cookieレスポンスヘッダの例

Delete-Cookie: foo, fizz

cookie nameを羅列することで、それらのcookieを消去するように指示できます。

議論

すでに、Cookieを消すにはいくつかの手段があります。

  • 方法1: expiresを過去の日付を指定することで消去することができますが、domain属性とpath属性を一致させる必要があります。
  • 方法2: Clear-Site-Data ヘッダを使用してcookieを全て消す。

W3Cで定義されているClear-Site-Dataヘッダを拡張して個別にCookieを消せるようにしても良いと思いますが、IETF HTTP WGで議論する方向になったようです (該当Issue)

DNSサーバへの疎通性確認に使う probe.resolver.arpa の標準化

一部の実装は、DNSサーバとの通信可能か確認するのにDNSクエリを発行します。このクエリを「DNS プローブ」と呼びます。

DNSプローブで使用するクエリ名として "probe.resolver.arpa" を使うことに標準化しようという提案が出されています(具体的なクエリ名は変更される可能性がある)。

提案は『Standardized Query Name for DNS Resolver Reachability Probes』としてMetaやGoogleの方らの共著となっています

DNSプローブのユースケース

提案仕様にかかれているユースケースの一部を紹介する

  • ネットワークが動作しているかどうかを判断する
  • クライアントがリゾルバの IP アドレスに到達できるかどうかを確認する
  • クライアントとリゾルバ間のネットワークパスの信頼性とパフォーマンスを評価する
  • 利用可能なトランスポートプロトコルUDPTCPTLS、QUIC など)を確認する
  • DNSゾルバ自体が動作していることを確認する

標準化する目的

指定したクエリ名は、NXDOMAIN応答を返すことを保証する。
これにより、DNSサーバ内で名前解決処理が行われないし、RDATAでトラフィックを余計に使う可能性がない。

Chromeの提案しているセキュリティ機能『Local Network Access』について

W3CのWeb Application Securityワーキンググループにおいて、Chromeチームから『Local Network Access』というセキュリティ機構の提案がされています。

これは、パブリックなWebページからローカルネットワークへのアクセスを保護するための仕組みです。ただし通信をすべてブロックするのではなく、特定のユースケースにおいては安全に通信を許可する必要があります。

背景

簡単に、パブリックなWebページからプライベートネットワークへの通信に関しておさらいしておきます。

攻撃の例とユースケース

パブリックなWebページから、プライベートネットワーク(例 http://192.168.0.1 )へリクエストを送信することができます。

  • imgタグやフォームでプライベートネットワーク宛にPOSTリクエストを送信する
  • JavaScriptのfetchでGETリクエストを送る (Simple requests)

クロスドメインのHTTPリクエストでは、CORS無しにはSimple requestsしか送れません。それでもCSRF攻撃が可能なルータの存在が知られています。 (参考URL)。

一方でパブリックなWebアプリケーションからプライベートネットワークの機器へ通信を許可したいユースケースもあります。例としてあげられているのは、機器側に複雑なWeb機能を持たせずに、パブリックなWebアプリケーションにUI機能を持たせるというものです。

そのため、通信をブロックすべきものはブロックし、許可されるものは通信を許可したいという背景があります。

Private Network Access (CORS-RFC1918)

プライベートネットワークへのCSRF攻撃の対策として、同じくChromeチームから『Private Network Access』という保護機能が実装されています。
developer.chrome.com

プライベートネットワークへの通信を許可する場合、Private Network Accessではプリフライトを伴います。これにより通信を意図してないプライベートネットワーク機器へのリクエストはブロックされます。

一方で、プライベートネットワークへの通信を許可したい場合は、プライベートネットワーク側の機器にも対応が必要でした。また、Mixed Contentsのリクエストへの対応についても課題がありました(プライベートネットワーク機器はhttpsに対応できないことも多く、httpになります)。

このPrivate Network Accessについて、MozillaWebkitからは好意的な反応は得られなかったようです。

Local Network Access

新しく提案されている Local Network Access の仕組みは単純です。これらのプライベートネットワーク側へのリクエストにパーミッションを設けることです。

HTMLでカメラアクセス等と同様に、ユーザエージェントが『ローカルネットワークリクエスト』許可のプロンプトを表示し、パーミッションを取ります。

パーミッションがなければ通信はブロックされます。

この仕組みについて、もちろんユーザが誤って許可することもSecurity & Privacy Considerationsに掲げられていますが、、、難しい問題のように感じます
GitHub - explainers-by-googlers/local-network-access: A proposal to restrict sites from accessing a users' local network without permission

おわりに

この提案は、2/19に行われるW3C WebAppSec WG MTGで初めて議論されるものです。今後の動向については追っていければと思います。
github.com

WebサイトがハングしたユーザのJavaScriptコールスタックを取得する

Webサイトが応答しなくなった場合、ブラウザ側が強制的に停止したり、タブがクラッシュしたりします。

その際の、JavaScriptコールスタックを取得する仕組みとして『Crash Reporting』という仕組みがあります。この仕組みを使うことで、Webサイトを閲覧しているユーザが実際にどこでハングしているのか、コールスタックを調査できるようになります。

具体例

下記のように閲覧したユーザの ハングしたURLが、JavaScriptコールスタック付きのレポートとして取得する事ができます。

(json内改行は見やすくするために修正)

Crash Reporting

Reporting APIという仕組みがあり、自身のサイトで起こったCSP違反やネットワークエラー(DNSエラー・TLSハンドシェイクエラーなど)を、任意のエンドポイントにレポートさせる仕組みが標準化されています。 NEL(network-error-logging)レポートも面白い仕組みなので興味があるかたは調べてみてください。

その中の一つに、Crash Reportingという機能があり、仕様通り指定するとJavaScriptコールスタックを送信させる事ができます。

設定の仕方

HTTPレスポンスヘッダで、レポート送信先エンドポイント通知することで、ハング時にレポートを送ってくれます

report-to: {"group":"default","max_age":31536000,"endpoints":[{"url":"https://asnokaze.report-uri.com/a/d/g"}],"include_subdomains":true}
document-policy: include-js-call-stacks-in-crash-reports

今回はレポート収拾にreport-uriというWebサービスを利用しておりますが、任意のURLを指定できます。
(report-uri便利でしたが、もうすぐ有償化されますね)

おまけ

動作検証に当たり、Webページをハングさせる事に苦慮しました.... "chrome://crash/" は使えず...
とりあえず、ボタンを押したら無限ループするようにし何回か施行した所、、、運良くクラッシュしたり、反応がないと表示されたりするケースがありました。

何かうまいやり方はあるんだろうか。。。

Cookie Layeringの動向及び関連仕様

2022年頃より『Cookie Layering』という議論があります。これは、Cookieに関する仕様を再整理し、ブラウザレイヤで必要な仕様拡張をしやすくするという議論です。

例えば、3rd Party CookieやCHIPS(partitioned cookie)の仕組みづくりをするうえで、RFC 6265 (および、改定作業中の6265bis)を土台にするには苦痛があるという意見もブラウザベンダーから出ています。

Cookie Layeringに向けての構想としては、2022年時点のW3Cでのスライドがわかりやすいと思います。

(TPAC Cookies Breakout Session - Google スライド)

RFC側は

Fetch、HTML(document.cookie)、Cookie Store API、Service Worker などのブラウザ固有の仕様はそれらのRFCを参照するようにするというものです。

このように、HTTPの仕様としてのCookieとWebプラットフォームとしてのCookieの扱いを整理します

現在の仕様策定状況

現在 Cookie Layering の実現のために提出されている仕様変更は以下のものが提案されています。

IETF側に出されているDraftでは、各処理がよりアルゴリズム的に書かれているのが印象的です。“Cookie Store” Conceptなど、まだまだこれから変更がありそうな感じもします。

また、各標準化団体の直近の議論としては

今後

引き続き議論が進められることでしょう。IETFでもこの取り組みについては前向き進んでいきそう。

TPACのスライドを見るに、Cookie Store周りの整理をしながら、『HTML』『Cookie Store AP』『3PC Blocking 』などの仕様側も合わせて変更案の作成を進めていくようです。

(https://www.w3.org/2024/Talks/TPAC/breakouts/future-of-cookies.pdf)

QUICでマルチキャスト通信を行うFlexicast QUICの提案仕様

この記事は『QUIC Advent Calendar 2024』 12/2の記事です。


インターネットで動画像の大規模配信が行われるようになって、トラフィックの増大が課題となっています。

そのような中で、QUICでマルチキャスト配信を行う議論は定期的に話題になります。マルチキャスト配信では、ルータ上で複製され必要な受信者に配送されるため、総トラフィック量を抑えることができます。

以前もマルチキャストQUICの提案仕様を紹介しました
asnokaze.hatenablog.com

今回は、Flexicast QUICという別の提案仕様が提出されているため簡単に紹介します

Flexicast QUIC

Flexicast QUICは『Flexicast QUIC: combining unicast and multicast in a single QUIC connection』としてIETFに提出されています。

アイディアとしては、QUICでマルチキャスト通信を行うというものですが、MultiPath-QUICをベースにしている点が新しいところです。

 
(引用: IETF 121スライド)

Flexicast QUICでは、各受信者とコネクションを張りながら別PATHとしてマルチキャスト通信を行います。このとき、マルチキャスト通信では共通の鍵を使えるようにしています。

通信の流れ

Flexicast QUICは以下の通信フローで、マルチキャスト通信の受信が行われる。
(なおIPレイヤの部分については、この仕様ではスコープ外である。つまり、マルチキャスト受信は行えるものとしてQUICレイヤが設計されている)


  • 通常のQUICハンドシェイクを行う。このときトランスポートパラメータとしてflexicast_supportを送信することで、本仕様のサポートを示す
  • サーバからFC_ANNOUNCEを送信し、マルチキャストの受信に必要なSource IP、Group IP、UDP Portなどを通知する
  • 受信者は、FC_STATE(JOIN)を送信し、マルチキャストフローの受信をサーバに通知する
  • サーバは、FC_KEYでマルチキャストフローを復号するためのマスターシークレットを送信する。
  • 受信者は、FC_STATE(LISTEN)で受信状態に入る

なお、再送制御などは、最初に確立したパスで補完することになる。

マルチキャストを受け取れない場合

Flexicast QUICではマルチキャストで送信数データは共通の鍵で暗号化する。仮に受信者がマルチキャストを受信できなかったとしても、同一のパケットをそのまま複数名に投げることでサーバ側の負荷を低減することが出来る。