SVGヤバイ 2013冬
Chrome 31がStableになって久しい。何が変わったのか思い出せないんだけど、ひとつだけ覚えてるのがこちら。
●(@156422) - b87d44f — Allow SVG images to not taint the canvas with drawImage/drawPattern
WebKitのパッチをマージしたものらしい。ちょっとずつ離れているらしいけど、まだお互い共有できるパッチもあるんだね。
さて、このパッチによって、CanvasでSVG画像を
マミさんは死んだ。
例で使われている画像的には良い気がしないけど、Webプラットフォーム的には良い変更だ。
試してないけど、SVG画像の中に
drawIm
age()
などで描画したとき、条件によってはそのCanvasがtaintされなくなった。
Tainted Canvasとは
CanvasにはdrawImage()
など、画像をCanvasに描画するメソッドがある。ここで、スクリプトとsame-originではないとこにある画像を描画してしまうと、セキュリティ上の都合からCanvasが“tainted”︵﹁汚染﹂︶という扱いになり、getImageData()
, toDataURL()
, toB
lob()
などができない。
ハックではない正攻法な対策としては、画像の配置場所をスクリプトとsame-originなところにするのが楽か。もしくはCORSのヘッダを設定してその許可したorigin以下に画像を配置し、それから画像にcrossorigin
属性︵DOMの場合はcrossO
rigin
︶を指定するなんてやり方もある。詳しくはMDNのドキュメント参照のこと。日本語訳がある。
●CORS有効な画像
●CORS設定属性
こんなニッチなの誰が訳したんだと思ったら自分だった…記憶がまったくない。
きたないSVG
さて、originまわりが良くなってもtainted扱いになるなんて場合がある。SVG画像だ。SVGは中にスクリプトや画像を書けちゃうので、危ないと判断されてWebKit/Blinkではこれまでどうあがいてもtainted扱いとなっていた。 あー説明めんどくさい…と思ってたらgyuqueさんが2年半前に同じことを書かれていた。しかもデモつき。なんと。 ●SVGヤバイ - 最速チュパカブラ研究会 今回のパッチで、SVG画像が内部で画像を呼んでない場合、そのSVG画像をdrawImage()
で読み込んでもtainted扱いにならなくなった。Chrome31で見てみたところ、一番右の列がすべて﹁OK﹂となったのを確認。
![図:単純なSVG画像をdrawImage()してもtainted扱いにならなくなった例](https://cdn-ak.f.st-hatena.com/images/fotolife/m/myakura/20131127/20131127190550.png)
<svg:image>
があるとアウトになるんだろう。