Webセキュリティメモ

何となく、自分の理解をまとめておきたくなったので、徒然と書き連ねます。

セッションとCookie

  • 誰からのアクセスなのかを判別するためには何らかの識別子(ID)が必要である。それがセッションID。
  • クライアントは、自分が誰であるのかを証明するために、通信の度にセッションIDをサーバへ送る必要がある。
  • 毎回送るという特性に親和性が高いため、通常、セッションIDはCookieで管理される。
    • 一部携帯電話(主にドコモのガラケー?)ではCookieが使えないため、GETパラメータで代用される事がある。
    • GETで管理するということはURLにセッションIDが載るということ。よってURLのコピペでセッションIDが漏れることも有り得る。ガラケーの仕様上、使われるのは致し方無いが、そうでない環境では通常この手法は採用されない。
  • セッションIDが盗まれると、セッションの有効期間が切れるまで、第三者が本人になりすまして不正アクセスすることが可能となる(セッションハイジャック)。
  • HTTP通信の場合、Cookieは平文で流れる。つまりセッションIDも平文で流れることになり、盗聴の危険性が生じる。
  • Cookieにsecure属性を指定すると、HTTPS通信の場合のみ、Cookieが送受信されるようになる。最近はHTTPS通信前提でウェブサービスが構築されることが多く(TwitterFacebook、…)、secure属性は良く使われる。
  • Cookieのexpires属性で有効期間を指定したほうが、万が一の時により安全ではあるが、最近はCookieで長い間セッションIDが維持される設計のウェブシステムが増えている。
    • ウェブブラウザを、スマホアプリなどと同列のクライアントアプリの一種と見なした設計とも言える。そう考えればスマホアプリと安全性は同程度である。

参考:HTTPヘッダにおけるCookie

HTTP/1.1 200 OK
Date: Sun, 03 Jun 2001 12:00:00 GMT
Server: Apache/1.3.14
Set-Cookie: num=123456; expires=Sun, 10-Jun-2001 12:00:00 GMT; path=/HTTP/
Last-Modified: Fri, 01 Jun 2001 00:00:00 GMT
Content-Length: 999
Content-Type: text/html
http://www.studyinghttp.net/cookies

AjaxCookie

SSLとMITM

  • SSLには「通信の暗号化」と「相手(通信先)が信頼できる(本物である)ことの証明」の2つの役割がある。
  • 巷で使われるSSLは、主として「独自SSL」「共有SSL」「オレオレ証明書によるSSL」の3種類ある。

独自SSL

  • SSLの最も正しい形。
  • ただし、証明書の発行所のグレードにより、信頼性は変わる。
    • メジャーなウェブサービスや銀行などは*1老舗VeriSignのClass3という最高グレードの証明書を持っていたりする。そのような証明書は取得の手間と値段がバカ高く、審査も厳しい分、信頼性が非常に高い。

共有SSL

オレオレ証明書によるSSL

  • SSLの一番アレゲな形。
  • ほとんどのモダンブラウザで「信頼出来ない証明書」という警告が出る。
  • フィンガープリントすら確認せずに、あのサイトは許可でオッケー、などと考えているとMITM(Man-in-the-Middle)攻撃(後述)を受けていることにすら気づくことが出来ないため危険。
  • よって、歴とした団体でありたいなら、オレオレ証明書は使うべきではない。
  ∧_∧  カタカタ   / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 (    )  ∧ ∧ < SSLには証明書が必要です…と。
 (    )  (,,°Д°)  \____________
 ̄ ̄ ̄ ̄ ̄ (つ_つ____
 ̄ ̄ ̄日∇ ̄\|  VAIO |\
        ̄   =========  \

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
| ほう、公開鍵暗号でセキュアプロトコルですか?
\
   ̄ ̄ ̄|/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ∧_∧       / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ( ・∀・)  ∧ ∧ < な、なんですか?あなた・・・
 (  ⊃ )  (°Д°;)  \____________
 ̄ ̄ ̄ ̄ ̄ (つ_つ____
 ̄ ̄ ̄日∇ ̄\|  VAIO |\
        ̄   =========  \

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
| 証明書は自分で作ってルート入れさせとけば無料ですませる…
\
   ̄ ̄ ̄|/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ∧_∧       / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ( ・∀・)  ∧ ∧ < それだとフィンガープリントの照合が必要になる…
 (     )  (;°Д°)  \____________
 ̄ ̄ ̄ ̄ ̄ (つ_つ____
 ̄ ̄ ̄日∇ ̄\|  VAIO |\
        ̄   =========  \

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
| フィンガープリントもSSLで送れば大丈夫、と。
\
   ̄ ̄ ̄|/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ∧_∧       / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  ( ・∀・)  ∧ ∧ < フィンガープリント送るときのSSLの証明書も照合しなきゃだめでしょ!!
 (  ⊃ )  (°Д°;)  \____________
 ̄ ̄ ̄ ̄ ̄ (つ_つ____
 ̄ ̄ ̄日∇ ̄\|  VAIO |\
        ̄   =========  \
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
http://takagi-hiromitsu.jp/diary/20050123.html#f01

MITM攻撃

  • 信頼出来ない証明書を許容すると、SSLによる暗号化を破ることが出来る。
    • ex. JB(Jailbreak, 脱獄)したスマホを用いれば、パズドラの通信内容を覗くことが可能。
  • MITM前提の設計をするのであれば、お金が絡む部分など、クリティカルな処理はサーバー側に集約する必要がある。
AliceとBobが、Bobのオレオレ証明書を使ったSSL通信を行う。
Eveは中間者でAliceとBobの暗号通信を盗聴する。

SSL(NAME) := NAMEのオレオレ証明書によるSSL通信

【通常の通信】
Alice ← SSL(Bob) → Bob

【MITM攻撃を受けている状態】
Alice ← SSL(Eve) → Eve ← SSL(Bob) → Bob

AliceがBobのオレオレ証明書をいつも信頼していると、
Eveのオレオレ証明書にすり替わっていても、そのことに気づかない。

CSRF(Cross Site Request Forgeries)

  • 端的に言えば「ユーザの意図しない自動投稿(submit)」。
  • 攻撃者は、CSRF対策されていないサイトに対して、適切なパラメータで適切なURLにGET/POSTするプログラムを書き、ばら撒く。
    • 最も手軽なのは、JavaScriptAjaxで自動投稿するプログラムを書き、罠サイトを用意し、URLを拡散する方法。
    • GET/POSTが出来さえすれば良いので、もちろんネイティブアプリで拡散しても良い。
  • 一般ユーザがばら撒かれたプログラムを実行すると、そのユーザのアクションとして、何らかのGET/POSTが行われる。
    • CSRF対策されていないSNSでは、セッションが持続していたら、意図しないメッセージを投稿させられることになる。掲示板やブログコメントにおいても同様。
    • 犯行予告であれば誤認逮捕も有り得る。
      • 遠隔操作ウイルスの横浜市への犯行予告*4による誤認逮捕。
    • ネット投票が荒らされる。
    • ショッピングサイトであれば意図しない注文をさせられる可能性も。
  • 対策の方針は「GET/POSTリクエストが正規のものであるかをチェックすること」
    • 一番お手軽な罠サイトのパターンを防ぐのであれば、リファラチェックが有効。
    • リファラは偽装できるので、リファラチェックだけでは、リファラを偽装する専用ツールに対抗できない。
    • 専用ツール対策としてはhiddenフィールドを使った固定トークン方式が一般的。
      • セッションIDは固定トークンであるが、HTMLのソース自体が流出する可能性も無いとはいえないので*5、セッションIDとは別の専用IDを作成して利用したほうが無難。
    • クリティカルな処理の最後のステップでパスワードを入れさせるという手法もある。
    • ワンタイムトークンを使う方法もある。
      • CSRFに限らず、ツールによる自動投稿・登録の対策としてCAPTCHAがあるが、これはワンタイムトークン方式の典型的な例であり、もちろんCSRF対策にも利用することが可能。
  • 警察が殺人予告などにシビアになっているため、今後は、特に一般に投稿メッセージが公開される系のウェブサービスでは、対策が必須になるか。
  • 参考

XSS(Cross Site Scripting)

外部からの入力シリーズ1

  • システム外からの入力を用いてHTMLなどを構成し出力する時に起きうる脆弱性
    • 一番単純な例「GETやPOSTで受け取ったパラメータを、そのままHTML出力する。」
      • script要素を含んだパラメータを送ることで、レスポンス表示時に任意のプログラムをWebサイトに組み込み、実行することが可能。
      • 罠サイトを用意して、攻撃スクリプトを含むパラメータでGET/POSTすれば、セッションハイジャック等ができる仕組み。
    • DBを経由するなど、間接的に入ってくる場合もある。
  • 対策方法は、出力時に適切にエスケープを行うこと。
    • 多重エスケープしないように、出力時にのみ行うように習慣づけることが重要。
  • HTML以外でもスクリプトを実行する手段があるので、注意する。

SQLインジェクション

外部からの入力シリーズ2

  • システム外からの入力を用いてSQLクエリを構成し実行する時に起きうる脆弱性
    • XSSと似たような話。
    • DBは個人情報の塊なのでXSSより深刻な被害になることが多い。
  • 対策としては、DBのPrepared StatementのPlaceholder機能を使うのが鉄板。

言うまでもないが、SQLのみならず、いわゆるeval関数やsystem関数などでも注意が必要。

バッファオーバーフロー

もしくはバッファオーバーラン

  • 低レイヤの脆弱性
    • メモリを直接扱うレベル。大抵C言語で発生。
    • その上に乗っているシステム全体を制御できる低レイヤだからこそ最も注意が必要な脆弱性。セキュリティは低レイヤを抑えたもの勝ち。
  • 典型的な例としては、想定よりも長い文字列が与えられて、スタックを上書きしてしまうなど。
    • スタックフレームのreturnアドレスを攻撃プログラムの先頭に…OS側の対策としてアドレス空間を実行毎に変えたり*6…などの話は巷に溢れているので省略。
    • 要するにgetsやscanfは使ってはいけませんのお話。
  • とにかくポインタを扱う時は注意が必要ということ。

その他

思いついたら書きます。

*1:FacebookTwitter東京三菱UFJ銀行でさくっと確認

*2:偽サイトではないと判別できるという意味で

*3:最近は減ってきている。

*4:おそらくメールフォーム経由?

*5:ブラウザのページ保存機能やEvernoteクリップなど

*6:ASLR

*7:実行や上書きはされないので