Lesson 10

クッキー

Lesson 10 Chapter 1
Secure属性

ECサイトやSNSなど、ログイン認証のあるWebサイトを思い浮かべてみましょう。一度ログインを済ませると、次回からIDやパスワードを求められることはありません。

以前も少しだけ言及しましたが、こうした機能は「Cookie」の技術により実現されています。Cookieは、現在のWebアプリケーションになくてはならない技術です。一方で、仕組みを理解しないまま使用するとセキュリティ上の問題に直結します。

そこで今回は、Cookieの詳しい仕組みを学ぶことにしましょう。これまで曖昧な理解にとどまっていた方も、この機会に正確な知識を身につけてください。

Cookieとは

Lesson4-4「セッションの取り扱い」の解説と重なりますが、CookieとはWebサーバーとWebブラウザの間でやり取りされるアクセス情報のことです。

実態として、Cookieはuser_session = OAwmVsQye8ZrnFzzgaのような変数名と値のペアで構成されています。WebサーバーはWebブラウザに対してこの文字列を送信し、クライアントを識別するための手がかりとする仕組みです。

Cookieを使用することで、たとえば次のような機能が実現します。

  • SNSなどのログイン認証でIDとパスワードが保持される
  • ユーザー閲覧履歴をもとにWeb広告が配信される
  • 問い合わせフォームなどで以前の入力内容が表示される

Cookie

Lesson4-4で解説した通り、Cookieはセッションを管理する目的でも使用されます。例:ECサイトでの買い物中ショッピングカートの中身が保持される

Cookieの仕組み

Cookieの仕組みを詳しく見ていきましょう。

Cookieは接続時にWebサーバーで作成されます。作成されたCookieはクライアントに向けて送信され、Webブラウザの内部で保存されます。以降、クライアントがCookieを発行したWebサーバーにアクセスする際は、毎回HTTPヘッダーにCookieを付与して通信を行います。

HTTP通信とCookieを併用することで、WebブラウザとWebサーバーの接続時、状態を持つことが可能です。

状態を持つとは、たとえばWebサーバーがHTTPリクエストのCookieを参照し、認証済みユーザーからの接続かどうか判定できるようになるということです。

HTTP通信は、以前の処理や通信の結果を内部状態として保持しないという性質を持ちます。そのため、n回目の通信で認証が完了したとしても、n+1回目以降の通信では、Webサーバーは認証された状態を覚えていません。

私たちが普段利用するWebサービスは、HTTP通信とCookieを組み合わせることで、認証された状態をWebサーバーと共有しています。

Secure属性とは

このように便利なCookieですが、ひとたび悪用されると重大な被害を招きます。

一例として、サイトAにログイン済みかどうかという情報をCookieが保持しているとしましょう。このとき、Cookieが流出すると、何者かが流出したCookieを利用して本人になりすまし、サイトAにアクセスすることが可能になります。

SNSであれば勝手に投稿されてしまいますし、ECサイトであれば商品の購入が可能です。企業のアカウントであれば、機密情報の流出にもつながるでしょう。

このような自体を避けるため、SSL/TLSで保護されたHTTP通信でない場合に、クッキーを送信しないようにするSecure属性というものがあります。

Secure属性のとりうる値は、真と偽の2つです。Secure属性を真にすることで、SSL/TLSで保護されたHTTP通信でない場合に、クッキーを送信しないようにできます。

次のChapterでは、Cookieの盗み取りを防ぐ「HttpOnly属性」について解説します。

Lesson 10 Chapter 2
HttpOnly属性

前回のChapterでは、Cookieに付与される「Secure属性」を紹介しました。同様にセキュリティ対策で付与されるものに「HttpOnly属性」があります。

今回は、このHttpOnly属性について詳しく見ていきましょう。

セッションハイジャックの危険性

Lesson9-1「helmetモジュール」では、セキュリティ攻撃の一種である「XSS(クロスサイトスクリプティング)」について言及しました。念のため確認すると、XSSは動的にWebページを生成するWebサーバーに対して、悪意のあるスクリプトを埋め込む行為のことを指します。

このXSSを悪用すると、訪問者(被害者)のWebブラウザで任意のスクリプトを実行できます。たとえば、攻撃者のサイトへCookieを送信するスクリプトを仕込めば、会員制サイトのログイン情報を盗み出すことが可能です。

結果的に、攻撃者は訪問者になりすましてログインを行い、クレジットカードの不正使用や登録情報の改ざん、個人情報の入手といった犯行に及びます。

JavaScriptによるCookieの操作

実は、クライアント側でCookieの値を操作すること自体は難しくありません。

次のように記述することで、JavaScriptを使ってCookieの値を操作できます。

sample.js
// すべての Cookie を表示
const cookies = document.cookie;

console.log(cookies);

// 名前が user の Cookie を更新
document.cookie = "user=userName";

HttpOnly属性とは

CookieにHttpOnly属性を付与すると、JavaScriptから値を書き換えられなくなります。主にXSS(クロスサイトスクリプティング)」の被害を防止する目的で付与される属性です。

このような自体を避けるため、JavaScriptからCookieの値にアクセスできないようにする「HttpOnly属性」があります。

HttpOnly属性がとりうる値は、真と偽の2つです。HttpOnly属性を真にすることで、上記のようにJavaScriptからCookieの値にアクセスできないようにします。

次のChapterでは、「SameSite属性」について見ていきましょう。

Lesson 10 Chapter 3
SameSite属性

前回は、Cookieに付与される属性として「HttpOnly」を紹介しました。今回は同様に付与される「SameSite属性」について解説します。

SameSiteは、「CSRF」と呼ばれるセキュリティ攻撃と密接に関係する属性です、

CSRF(クロスサイト・リクエスト・フォージェリ)

CSRF(クロスサイト・リクエスト・フォージェリ)とは、攻撃者が用意したWebサイトを閲覧中、訪問者(被害者)の意図と関係なく、情報やリクエストを送信される攻撃です。

この攻撃により、利用者の意図に反して商品を購入してしまったり、送金処理をしてしまったりといった被害が起こり得ます。

XSSとの違い

前述したXSS(クロスサイト・スクリプティング)とCSRFは、しばしば混同されがちです。XSSは訪問者のWebブラウザ上で不正なスクリプトが実行され、Cookieなどの個人情報が盗み取られます。一方、CSRFは攻撃者が用意したWebサーバーにおいて、意図しないリクエストが実行されます。それぞれ然るべき対策が異なるため、間違えないようにしてください。

このCSRF対策としてCookieに実装されたのが、「SameSite属性」です。

SameSite属性とは

SameSite属性は、現在のドメインから別ドメインへリクエストを送る際、Cookieをセットするかどうかを決めるものです。

具体的には、NoneStricLaxのいずれかを値として指定します。それぞれの値が持つ意味は以下の通りです。

SameSiteの値 クッキーを付与するリクエスト
Strict ・same-siteに対するリクエスト
Lax ・same-siteに対するリクエスト
・GETリクエストかつページ遷移が伴うリクエスト
None ・same-siteに対するリクエスト
・cross-siteに対するリクエスト

ここで言うsame-siteとは、アクセス先について、画像の下線部分が変わらないサイトのことです。また、cross-siteとは、画像の下線部分が変わる(same-siteでない)サイトを指します。

same-site.png same-siteの説明画像

注意点として、SameSiteを付与したからといってCSRFが完全に防げるわけではありません。リクエストを強制する先がセッションを使用しないサイト(匿名掲示板など)の場合、正常に処理されてしまいます。

とはいえ、CSRFの被害を防ぐにあたって、same-site属性の付与は十分な効力を発揮します。