2013年2月3日日曜日

svgのセキュリティについて考える

便利な道具も使い方によっては凶器になりうるというのは洋の東西を問わず真理であり,svgそのものは非常に便利な仕組みですが,誤った認識のまま普及してしまうことは実に危ういことです.とりわけsvgの歴史的な経緯を鑑みるに,svgを取り巻く現状は非常に危ない状態にあると言えます.

今回はsvgは「なぜ危ないか」と言った面に焦点を当て,筆者の見解を述べて見ることとします.
※まとめを追加しました.(なんか書き忘れてたので・・・)

セキュリティを考えるきっかけ


なぜこのような事を考えるに至ったのかというと,twitterにおいて次のような記事が紹介されていたからです.
かいつまんで言うと,「svgの仕組みを使えばスクリプトを使わずにに悪さを行えるよ」という内容です.中身を読んでみると判るのですが,結構ショッキングな内容です.状況や実現可能な環境に制限があるものの,パスワードの入手やキー入力の追跡等への可能性について論じられています.

筆者もそれまでsvgを便利なファイル形式としか考えていなかったため,この記事を読むことで漠然とした不安を憶えました.そのためこれはもう少し掘り下げて注意喚起すべきと感じたのです.

静的な画像ファイルとしての誤解


上の例ではsvgフォントとsmilアニメーション及びhtml5,css3を巧みに利用したものでしたが,ここでちょっと考えてみてください.我々は漠然とsvgは単なる画像形式だと考えていないでしょうか?

これまで一般的だったjpg,pngといった画像形式は概ね静的に画像を定義するため,(画像の内容はともかく) ファイルとしては無害なものと考えて差し支えありませんでした†.そこへsvgという新しい画像形式が加わっただけ,そう思い込んでしまうのは標準的なユーザーであれば十分にありうることでしょう.つまり「svg=jpgやpngのようなもの(画像形式)=安全」と言った図式が成り立ってしまうのです.

†ただし,これらのファイルが常に安全というわけではありません.かつてラスタ画像を表示する際のブラウザのセキュリティホールを突いたウイルスが蔓延したことがありました.

実はここに大きな落とし穴があるのです.svgはxmlをベースとしており,グラフィックを描くだけでなく,内部にjavascriptによるスクリプトコードを挿入することで,様々な処理を行わせることができます.つまり,svgそのものは決して安全なファイル形式ではなく,むしろhtmlに近い文書形式として考えるのが筋なのです.

実際,svgにはforeignObject要素と言ったxhtml要素を挿入するための仕組みが備わっており,この仕組みを用いることでsvg画像にフォーム送信機能を付けることもできます.つまり,webブラウザでsvgを表示するケースにおいて,svg文書とhtml文書との間に機能的な差異は存在しないことになります.(よってxssやxsrfも十分にありえます

しかしsvgで作画する時,ほとんどの人はイラストレーターやinkscape等のドローイングツールを用いるでしょう.このようなツールを使ったsvg画像には通常htmlやスクリプトのような要素が含まれないため,概ね安全なsvgファイルとなります.また,html5が普及する以前はこのような安全なsvgファイルの使い方がメインであったため,危険なsvgが存在すること自体に気が付きにくいのです.

従って大多数のユーザーがその危険性を認識しないま,svgに精通したクラッカーが作成した危険なsvgコードがばら撒かれてしまう可能性があるのです.これはsvgそのものに欠陥があるわけではなく,我々の認識如何によっては元々svgが抱えている(htmlと同程度の)リスクを増幅してしまうことがあるということなのです.

(何も対処しなければ,いずれhtmlで経験したことをそのまま繰り返すことになりかねません.)

ケーススタディ・画像投稿サイト


それでは実際に問題のあるケースについて考えてみましょう.
画像投稿サイトにおいてsvg形式をサポートするものはほとんど見受けられませんが,例えばこのような仕組みを実現したとしましょう.その際に次の条件を満たした場合に重大なセキュリティホールとなります.

(1)フレームを跨いだ情報の搾取

  1. メインとなるhtmlページと投稿されたsvg画像とが同じドメインである.
    (同一生成ポリシーを満たす)
  2. svg画像をobject要素で表示している.
この場合,object要素が生成するインラインフレーム内部にsvgグラフィックが表示されるでしょう.すると,同一生成ポリシーを満たすため,インラインフレーム内部から親フレームの内容にアクセスすることが可能となります.従ってsvgに外部に情報を送信するようなスクリプトが挿入されていた場合,情報の漏洩が発生することとなるでしょう.とりわけ「svg画像はobject要素で表示する必要がある」といったie時代の古い常識もあり,中々その危険性について把握できないのも問題です.

対処策としてはsvgと言えど,object要素でsvgを表示せずにimg要素で内容を見せる方法があります.

svgには参照モードと呼ばれる仕組みが定義されており,object要素とimg要素とで動作が異なります.一般にimg要素で表示したほうがよりセキュアな環境でsvgを表示することが出来るのです.つまりobject要素によるsvgの表示は自作のファイルであったり,出処の確かなものに限るべきなのです.

また,メインとなるhtml文書とsvg画像を表示する際のドメインを変えるのも有効です.しかしこれだけでも対策は不十分です.というのも次のようなシナリオが考えられるからです.

(2)ブラウザのセキュリティホールを突く

  1. サイトを閲覧したユーザーがimg要素に表示されているsvg画像をローカルにダウンロードする.
  2. そのsvg画像をwebブラウザで開く.
  3. webブラウザにセキュリティホールが存在し,svgの中にそれを突くコードが記述されている.
  4. その結果意図しない動作を引き起こす.
svgファイルを直接webブラウザで表示した場合,より自由度の高いモードで動作します.従って,動画投稿サイトで表示した時と異なる動作を行います.従って一般ユーザーには中身を隠蔽しつつsvgファイルを拡散させることができるのです.しかも一般ユーザーはsvgの危険性には無知ですから,webブラウザでsvgを表示したとしても何も気が付かないでしょう†.

†ブラウザによってはsvg文書内部のスクリプトの有無をユーザーに表示するでしょう.しかしsvgの危険な面を十分に理解しないままでは大部分の人はその内容を無視してしまうでしょう.
(ここがhtmlとsvgの辿った歴史的な違いです.我々はまだsvgで痛い目に遭っていないのです

現状svgの実装は進行中であり,新たなセキュリティホールが発見される可能性を否定出来ず,このシナリオも実現性は低いとは言え,悪意有るファイルを拡散させるリスクを無視するわけには行きません.

対処策としては,とにかくサーバー側でscript要素やイベント属性を削除し,検疫した結果のみをユーザーに表示することが考えられます.画像投稿用のsvg文書であれば,もともとスクリプトを仕込む必要性が無いはずですから,有効な対処策と考えられます.

まとめ

  • 一般ユーザーはsvgを無害なファイルと思い込みやすい.
  • svgはhtmlと同等の文書形式であり,適切に加工した上でユーザーに手渡す必要がある.
  • svgは利用の仕方により動きが変化する.一面的な見方をするのは非常に危険.
  • 我々はいまだsvgによるセキュリティインシデントを経験していないため, 万が一の被害が広がる可能性がある.

このように簡単に考えても危険なシナリオが見つかってしまいました.先ほどのsvgフォント・smilアニメーションのようにこれからもsvgを絡めた危険なシナリオが見つかることでしょう.

関連する記事)
Google、「Chrome 22」の極めて深刻な脆弱性に対処 ハッキングコンペで発覚


現状html5を取り巻く環境は非常に複雑となっており,その危険性について論じられることも多いのですが,その影で忘れられがちなsvgについてもweb技術の一角を担っている一員として,確かな認識でセキュリティリスクを論ずるべきなのです.

0 件のコメント:

コメントを投稿