- WebRTCを使った一般的なユースケースでは、Webサーバーを介してセットアップを行う
- WebRTCを使うためのJavaScriptはブラウザに実装されているが、それをコールするのはサーバーから渡されるスクリプトである
- 一般的なこれまでのVoIPのシステムとは異なり、新たなセキュリティリスクが伴う
- もしかしたら、ページを表示しただけでどこかに通話が開始され、録画されたりするかも
- DoS攻撃に利用されることもありうる
- いつもの
- ブラウザはユーザーを保護する責務がある
- もし悪意のある攻撃者に誘導されてページを閲覧したとしても、安全であることが重要
- WebRTCについても同様に要件を満たす必要がある
- HTMLもJSも、ブラウザのSandbox内で実行され、そのコンピュータに対しては隔離されてる
- Web攻撃者とネットワーク攻撃者がいる
- ネットワーク攻撃者については、RFC3552
- ブラウザはローカルのリソース(ファイルやカメラなど)にアクセスできる
- しかしWebサーバーからはアクセスさせない
- ファイルアップロードもユーザーが明示的にファイルを選択する必要がある
- Flashも、カメラやマイクへのアクセスには許可が必要
- なんらかの実行ファイルも、ダウンロードはできても実行はされない
- ブラウザからは他のサーバーへのアクセスができる
XHR
などで
- ただしそれにもSame-Origin Policyの制約がかかる
- JavaScriptの変数の参照も、オリジンをまたいでおこなうことはできない
- SOPは堅牢であるが、不便なこともある
- 複数のAPIサービスのマッシュアップなど
- そのために
CORS
の仕様がW3Cにはある- Cross-Origin Resource Sharing
- CROSS-PROTOCOL攻撃には注意が必要
- 本文なし
- ユーザーの同意なしに、通話を開始してはいけない
- ここでいうユーザーの同意とはなにか
- どのメディアを送るのか
- 誰に送ろうとしているのか
- ローカルデバイス利用への同意は、それが送信されることへの同意にもなり得る
- HTTPSなどで暗号化された経路であっても、同意は必要
- デバイスに対するプライバシー上の同意
- ネットワークにトラフィックを送信することへの同意
- カメラやマイクだけでなく、画面共有についても考慮が必要
- カメラやマイクよりもシビアな問題
- 思った以上にシェアされてしまう可能性がある
- とつぜんの通知であったり、共有を止め忘れたり
- SOPでそのページの内容を見ることができなかったのに、画面共有ならそれが見れてしまう
- パスワードやトークンなどを写し取られてしまったらどうする
- 通話に関しては多様なパターンがあって、それぞれ一様に同意を得ることはできない
- 特定のサイトで不特定多数と話すパターン
- 長い期間、カメラやマイクへのアクセスを許可することになる
- 通話しながらゲームができるとか
- 多くの異なる人と話せる場合は、誰と話しているのかがわかる必要がある
- ショッピングサイトなどにある「担当者と話す」のパターン
- こちらから話したい場合には同意をする
- ただしそれはいつでも通話をよこしても良いという意味ではないはず
- そのサイトがマイクやカメラを利用していることを表示するUIも必要
- 前述の通り、ブラウザのSandboxはオリジンごとである
- たった1度の通話で許可したことを、未来永劫の許可と捉えられるわけにはいかない
- そこをケアするためにはいくつか同意に区分が必要
- 3つの区分
- 個人の同意: 通話ごとに許可を
- 通話相手に対する同意
- 通話内容が暗号化されることについての同意
- UIを出すだけでいい話ではない
- ユーザーが何も考えずにOKを押すこともある
- 通話相手への同意は、悪意あるサイトの場合に嘘かもしれない
- 通話相手を識別するなにかがあれば
- draft-ietf-rtcweb-security-arch でも言及がある
- オリジンによるセキュリティの担保は、Web攻撃者には有効
- ただしWebRTCではネットワーク攻撃者についても考慮する必要がある
- HTTPのページで許可をしたあとに、脆弱なネットワークで攻撃されるシナリオ
- HTTPコネクションを差し替えられて、異なるサイトでも許可したことにされてしまう
- 脆弱なネットワークから離れたあとも影響され続ける
- Webアプリから無制限にネットワークアクセスはできない
- これができてしまったら、攻撃プラットフォームに使われてしまう
- トラフィック送信の同意をするためのハンドシェイク以外のトラフィックは許可なく送られてはいけない
- ただし帯域の過剰仕様を防げるわけではない
- WebRTCを使えば同意なしにトラフィックを送信して帯域を圧迫もできる
- よって適切な輻輳制御がWebRTCプロトコルに実装されている必要がある
- 同意を得るにはハンドシェイクが必要で、ICEにもその仕組みがある
- 安全にハンドシェイクをするために、応答を偽造されないための仕組みが必要
- 例えばICEの場合、STUNのトランザクションIDは必ずブラウザが生成する
- トラフィックが流れる間ずっと、受信することを希望していることを確認する仕組みも必要
- ICEの場合はそれがRFC7675
- TCPが使われる場合は、WebSocketのようにマスキングが必要
- DTLS上ではマスキングは不要
- TURN TCPでのSRTPパケットは、WebAudioと緻密なタイミング制御によって制御できる
- ICEが使えないクライアントとの互換性
- 攻撃者が偽造できないなんらかの値を含めてやりとりする必要がある
- ICEを使わずにSTUNをやり取りする場合
- RTCPを暗黙的に到達確認に使う場合
- WebRTCはICEを使うものなので、STUNだけを使ってもユーザー名とパスワードを検証できない
- RTCPを使う場合も、そもそもRTCPがサポートされてないこともあるのでダメ
- 他にあるとすればICE-Liteの実装のような場合
- ICEで経路を送ると、IPアドレスがわかる
srflx
なアドレスは地理的な情報をも含む可能性がある- TURNを使ってそういった情報を秘匿したいと思うかもしれない
- VPNを介して接続していても隠しきれない可能性もある
- 通信のセキュリティについて
- 映像と音声について、改ざんやなりすましなどに耐性が必要
- RFC5479
- 攻撃の分類は2つ
- 受動的な攻撃: 古い通話に対する攻撃
- 能動的な攻撃: 通話中に対する攻撃
- 通話後に、その内容を復元しようとする攻撃
- これに対しては、トラフィックを暗号化している鍵へのアクセスが焦点になる
- WebRTCでは公開鍵ベースの鍵交換が推奨で、できればPFSな仕組みであるべき
- また保存された鍵へアクセスするAPIは提供してはいけない
- 通話中を狙った攻撃について
- 具体的にはMITM攻撃を防ぐのは困難である
- Fingerprintの仕組みや、3rdの認証機構を用いるなどするしかない
Key Continuity
について- 悪意があっても、特定の公開鍵に対して秘密鍵を生成することはできない
- SSHのように対応する鍵の情報を管理しておけば、それが変わったときに気付くことができる
- しかしWebRTCでは、複数のコンピュータ、ブラウザを使うことは一般的なので有用ではない
- ブラウザが信頼できるUIで、誰に対する呼び出しなのかを明示する必要がある
- ZRTPで使われるSASという仕組みがある
- Short Authentication String
- 通話するAとBにそれぞれ決められた単語を読み上げさせて確認する
- しかし音声変換システムなどでなんとかできてしまう
- ブラウザもSAS交換を要求しているUIを出すことしかできない
- そしてそれは無視されることもあるだろう
- 3rdの認証システムを使って個人を識別することもできる
- 使わないよりは面倒にはなる
- ただし昨今は一般的にもなりつつある
- MITMに対してももちろん耐性がある
- WebRTCで送られるメディアは
MediaStream
というAPIで操作される- 通話をするサイトがそれを操作できる
- サイトが
MediaStream
を変更していない保証を得たいかもしれない- 一般的にはユーザーはそれを気にしてはいない
- これを実現するには、
MediaStream
へのアクセスを許可、取り下げる仕組みが必要
- 通話相手がそもそも悪意がある場合
- 通話内容を録音したり横流ししたり
- 変声や顔を隠しているなど
- WebRTCのようなオープンな仕組みでは関与しない
- 本文なし
- 匿名性との関係について
- DTLSの証明書やRTCPのCNAMEをリセットする仕組みが必要
- IPアドレスも個人を特定する要素になり得る
- ブラウザに搭載されてるAPIの有無ですらFingerprintとして使われるかも
- 機能性とリスクのバランスを取る必要がある
- この文書自体がセキュリティに関するものであった