ログイン周りとセキュリティ関連の情報収集
SPAでのログイン・ログアウト機能実装方法のベストプラクティスが分からなかった事と、脆弱性についての知識が不足しているので情報収集。
session認証とトークン認証の違い。
- cookiesを使ったsession認証
- トークンを使った認証
- Tokenによる認証も、Cookieと同じく、まずはクライアントがWebサーバーに接続(Login)した際に、Tokenが返されます。ただCookieと違ってあ、サーバーにその情報を保存はしません。「認証に成功した」というToken(いわゆる「認証情報」)を持ち、リクエストする度にリクエストヘッダにTokenを含んで送っています。
また、railsを使った認証系のセキュリティは以下も参考にします。
Railsアプリの認証システムをセキュアにする4つの方法(翻訳)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社
実装方法の検討
JWTとは
cookieとは別によくSPAで認証系で使われる技術としてJWTというものがある。
JWT・Cookieそれぞれの認証方式のメリデメ比較 - Qiita
Cookieはサーバ側でsession情報を持つ。CookieにはsessionIdを入れており、リクエストの都度sessionIdに紐づくサーバ側sessionデータを参照している。 Tokenはクライアント側で「認証に成功した」という情報(=Token)を持ち、リクエストの都度それを送る。
SPAの認証方法
SPAを使った認証系は(OauthやSSOを除く)大まかに4つに別れる
- サーバー: Sessionトークンを発行 -> クライアント: Cookieに保存
- サーバー: Sessionトークンを発行 -> クライアント: Web Storageに保存
- サーバー: JWTを発行 -> クライアント: Cookieに保存
- サーバー: JWTを発行 -> クライアント: Web Storageに保存
4の様にSPAではフロント側にセッション情報やJWTを保存する際HTML5の新機能local storage(web strage)と呼ばれる領域を使ってブラウザ側に保存するパターンも多いらしいのですが、下のリンクの様にセキュリティ上脆弱性を孕む(scriptを使うと簡単に中身を覗ける)様です
HTML5のLocal Storageを使ってはいけない(翻訳)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社
local storageはあらゆるJavaScriptコードから自由にアクセスできてしまいます(データ保護的なものはありません)。これはセキュリティ上非常に重大です。
webサイトに悪意のあるJavaScriptが埋め込まれたサイトの外部リンクなどを使って、local strage上のデータを全てコピーする事もできます。
とのことでXSS(クロスサイトスクリプティング)攻撃で簡単に情報を取られる危険性があり、セキュリティ上認証情報をweb storage保持しておくのは望ましくないとのことで、2と4はやめます。
残る1と3ですが、cookieでhttpOnly属性をtrueにすれば、JavaScriptからcookieにアクセスできなくなるのでXSSの被害を緩和できます。(JavaScript の Document.cookie API にはアクセスできなくなる)
調べた結果JWTである理由も今回は特に無いと思いますので、
普通に1のセッションをcookieを使って実現したいと思います。
また、その場合CSRFは防げないためcookieのセッションIDとは別にCSRFトークンも実装します。
Railsの場合、例えばフォームでpostするときは自動的にトークンが生成されブラウザサーバ間でCSRF対策がなされるのですが、APIの場合は自分で対策しなくてはいけません。
最初はCORS (Cross-Origin Resource Sharing)の設定で許可されたオリジン以外のからアクセスは弾かれるので、CSRFトークンは必要ないのではないかと思いましたが、CORSはサーバへのアクセスを防ぐものではなく、サーバからのレスポンスをクライアント側で読めなくするものなので、CSRFによるサーバへの不正なリクエスト自体は成功してしまいます(例えば罠サイトで情報を書き換えようとして不正なPostリクエストを送った場合でも、レスポンスは帰ってこないが、このPost自体は成功してしまう)
APIのドメインが認証用Cookieのドメインと同じ場合:CookieのSameSite属性をLaxに指定 APIのドメインが認証用Cookieのドメインと異なる場合: CookieのSameSite属性をNoneに指定し、Secure属性を付与する CSRF tokenを利用する
cookieの属性
cookieはいろんな属性がありますが、セキュリティに関連する設定属性は以下になります。
- Secure属性
- trueの場合CookieはHTTPS通信でしか送受信されない。
- HttpOnly属性
- JavaScriptからcookieにアクセスや操作をすることが出来ない
- SameSite属性
参考にした書籍、情報
徳丸 浩 『安全なWebアプリケーションの作り方』