安全なWebアプリケーションの作り方

体系的に学ぶ 安全なWebアプリケーションの作り方 第2版の3章をスライドにまとめてみた

はじめに

ミラスタのクニタです。

普段はRuby on Railsのエンジニアとして日々楽しくプログラミングをやっています。

私の自己紹介記事はこちら

さて今回はエンジニア初学者に向けてセキュリティや脆弱性への攻撃手法について体系的に書かれた本を読んでまとめてみました。

基本的なWebの仕組みから学習することができるので非エンジニアの方にもぜひみていただければと思います!

参考文献

今回まとめてみた本はこちら。

安全なWebアプリケーションの作り方

安全なWebアプリケーションの作り方

脆弱性に関しての技術的な本といえばこれというくらい有名な『徳丸本』です。

(ただしサンプルコードがPHPになるのでペチパーの人以外が読むのは少し苦労します苦笑)

著者はセキュリティ技術における日本の第一人者的な方です。

IT業界で唯一、国家資格を提供しているIPA(独立行政法人情報処理推進機構)が発行する「安全なウェブサイトの作り方」への寄稿もしています。

こちらはセキュリティ脆弱性を突く攻撃手法をまとめたものです。

XSSやSQLインジェクションなど、聞いたことがある人もいるかもしれません。

これらの内容は本書における4章に当たる部分となっており、私の次のエントリーでまとめたいと思っています。

さて徳丸本の紹介に戻りますが、本エントリーでは3章をまとめています。

3章の位置付けは以下の通りとなっています。

  • Webアプリケーションにおけるセキュリティの基礎となるHTTPやCookie、セッション管理
  • 同一生成元ポリシーとCORS

1章では脆弱性とは何かということや、脆弱性が生まれる理由を説明し、2章でハンズオンで進めていくための実行環境をセットアップします。

これを踏まえ、3章では大きく2つのテーマを学習します。

一つは脆弱性が潜む、基本的なWebの仕組みで、もう一つはブラウザが持つセキュリティ機能の紹介です。

これらを押さえた上で、本格的な脆弱性の原理と対策を4章以降で学習していきます。

では早速始めていきましょう!!

※クリックでスライドが閲覧できます。


安全なWebアプリケーションの作り方

ステートレスなHTTP通信とは

最初にWebの基本であるHTTPの特徴について考えてみたいと思います。

ここではWebのルールであるHTTPと、HTTP通信の仕組みと特徴について説明していきます。

HTTPとは?

みなさんは日頃意識することなくGoolge ChromeやSafariなどのWebブラウザを利用して情報収集しています。

この情報収集において利用される技術がHTTPです。

HTTPとは、Hyper Text Transfer Protocolの略でクライアント(ブラウザ)とWebサーバのやりとりにおける規格(ルール)です。

このHTTP通信によって普段技術的なことを意識せず、情報を収集することが可能となっています。

リクエストとレスポンス

次にHTTPで通信する仕組みについて考えてみましょう。

クライアントとサーバはそれぞれ独自の通信を行なっています。

それがリクエストとレスポンスです。

リクエストとはサービス要求のことです。

クライアント(ブラウザ)からURLにアクセスすることでリクエストが走ります。

一方レスポンスは、クライアントからリクエストされたものをサーバ(サービス提供側)内で処理し、その結果を返すことです。

HTTP通信はこのやりとりの連続で成り立っています。

ステートレスとは?

HTTP通信はよくステートレスな通信だと言われます。

State=状態、less=ない

つまり状態を保持しないという意味です。

HTTP通信では常に通信はステートレスとなっています。

誤解を恐れずいえば、リクエストとレスポンスは常に1対1となっていて、前の通信状態を覚えていないということです。

例えばコンビニでの店員さんと顧客のやりとりを考えてみましょう。

顧客「肉まんはありますか?」店員「はい、あります。」

これがリクエストとレスポンスです。

では次に進んでみましょう。

顧客「ではそれを1つください。」店員「それって何ですか?」

おかしいですね、前の会話を前提としたやりとりが成立していません。

日常会話であれば前の文脈をお互いが覚えているのでこういった問題は起こりませんが、

HTTPの場合は通信のやりとりがステートレスなためこの問題が常に発生します。

とはいえ、Webでの通信も前の文脈を覚えて欲しいときがあります。

例えばログイン認証を備えたWebシステムやECサイトなどです。

ログイン状態を保持していないとその人が持つ権限でWebシステムを利用することが困難になったり、

ECサイトで買い物かごに入っているものが画面遷移するたびになくなってしまうといった問題が発生してしまいます。

そんな問題を解決するためにWebには大きく分けて2つの手法が用意されています。

状態を保持するための2つの手法とは

HTTPでは状態を保持するための仕組みが大きく2つあります。

それがhiddenパラメータセッションです。

どちらも状態を保持する目的で利用されるものですが、もしあなたがプログラマーなら

状況に応じて使い分けることも意識して考えてみてください。

hiddenパラメータとは

まず一つめはhiddenパラメータです。

hidden=隠されている、という意味通り、隠されたパラメータを次の通信に引き渡すことができます。

スライドではログインの際に入力→確認→完了画面に遷移する例を挙げています。

まず、入力画面で入力したデータはフォームのinputタグの中で次の画面に渡ります。

次の確認画面でページのソースを表示すると実際に入力したデータがhiddenパラメータのvalue(値)に保持されています。

そして最後にその値が引き渡されて認証機構(Authentication System)を通してログインが完了するという仕組みとなっています。

実際にはもっと複雑な仕組みになっていますが、基本的なログイン機能の仕組みとして覚えておくと役に立つでしょう。

セッションとCookieとは

もう一つ状態を保持するための仕組みがあります。

それがセッションです。

セッションもhiddenパラメータと同じように、通信のたびに保持しているデータを受け渡すための仕組みです。

そもそもの意味としてのセッションとは通信におけるひとかたまり(=単位)のことで、

多くの場合、そのサイトの閲覧を初めてから閉じるまでの一連の行動を1セッションとしています。

Google Analyticsなどではそのサイトにおけるユーザーの行動にどういう傾向があるかを分析する要素としての性格を持っています。

Cookieとはセッションにおけるデータのことです。

正式にはHTTP Cookieと言いますが、Cookieは初回通信時にサーバで発行され、

その後クライアント側(つまりブラウザ)で保存され続けます。

これを通信のたびにサーバ側と受け渡しすることで情報を保持することができます。

アフィリエイト業界ではアフィリエイターのアフィリエイトリンクの情報を保持して

どのアフィリエイターが売上に貢献したのかで報酬を支払う仕組みとなっています。

その際もこのCookieを利用しているわけですね。

状態を保持する2つの手法の使い分け

HTTPというのはステートレスな通信なのでhiddenパラメータやセッション機構(Cookie)で

ステートフル(状態を保持し続ける)な通信を擬似的に実現しているのは理解できたでしょうか?

ではこのhiddenとセッションはどのように使い分けるのでしょうか?

そこで考慮する必要があるのはセキュリティや脆弱性です。

ポイントになるのはその技術の複雑さで、hiddenパラメータはセッションとは異なり

技術的にはとても簡単な仕組みになっています。

したがってセキュリティ面では脆弱性が入り込む余地が比較的少なく、

なるべくこちらを使いたいです。

しかしセッションで利用するデータをhiddenパラメータで管理すると

第三者からの改ざんはできないものの、本人が書き換えることは可能なので、

ステートレスな通信を担保することが難しくなってしまいます。

したがって本人にも改ざんされたくないデータに関してはセッションで管理し、

それ以外はhiddenパラメータを利用するのが基本となります。

ブラウザのセキュリティ機能とは

今までの話を踏まえて、今度はブラウザのセキュリティ機能について考えて行きましょう。

ブラウザというのはクライアント側でサーバから受け取ったデータをレンダリング(描画)するのが主な仕事です。

そのなかで不正なデータを排除するためのセキュリティ機能も持っています。

それが同一オリジンポリシーです。

同一オリジンポリシーとは

同一オリジンポリシーとは誤解を恐れず言えば、

「同じオーナーであるサイトコンテンツ同士のデータのやりとりのみ許しますよ」という機能です。

この同じオーナーであるサイトコンテンツかどうかは以下の3つが全て一致している場合をさします(=同一オリジン)。

  • ホスト
  • スキーム
  • ポート

これらが一致しないコンテンツから別のコンテンツを取得して画面を描画しようとした場合、

このポリシーにしたがって悪意のあるスクリプトが制御(=実行が制限)されます。

これによってユーザー固有のデータが悪意のある第三者に取得されることを防ぐことができます。

この考え方をサンドボックス(=砂場)と言います。

つまり、砂場で遊んでいた子どもを家の中に入れないようにしようとするのと同じ原理です。

ブラウザのsandbox機能

ブラウザのsandbox機能

砂場から帰ってきた子どもは当然砂だらけなので、いったん外で服を脱いだり水で洗い流してから家の中に入れます。

ちなみにブラウザによってこのポリシーの適用範囲は異なりますので気になったら調べてみてください。

CORSとは

一方で現在では異なるオーナーのサイトコンテンツからのデータを取得したい場合も増えてきました。

例えばAPIを利用したマイクロサービス間での通信です。

プログラム開発において開発が進んでくると、サービス自体がモノリシック(=一枚岩)になると同時に

プログラムのソースコードも膨大になり、障害が起きた際に原因の特定がより難しくなります。

そこでサービスを機能別に分割して、その機能単位でAPIを通じてデータをやりとりする、

というのがマイクロサービスの考え方です。

マイクロサービスだけでなく、APIを使ったデータのやりとりは今後も増え続けると予測されます。

そこで登場するのがCORS(Cross-Origin Resource Sharing)と言われる、異なるオリジンでもデータのやりとりができる仕組みです。

つまり異なるオリジンでも事前に通信してもよいという許可を与えておき、

その許可を持っている異なるオリジンからのアクセスのみ許すというものです。

CORSが適用される条件はどのようなリクエストをするかによって異なるため、今回は割愛させていただきますが、

世の中の要求にしたがってそれに答える技術としてCORSという考え方ができたということです。

まとめ

いかがだったでしょうか?

今回はWebの仕組みと、ブラウザのセキュリティ機能に関してエンジニア初心者でも理解しやすいよう

なるべく平易な言葉でまとめてみました。

Webの仕組みはWebエンジニアなら必ず知っておくべき基本的な技術となっていますし、ブラウザのセキュリティ機能もレンダリングエンジン以外では日頃意識しないもののとても重要な機能です。

これを機にご自身でもっと深く調べてみてください。

きっと新しい発見があるはずです!

それでは次は4章でお会いしましょう〜