Skip to content

Instantly share code, notes, and snippets.

@mala
Created January 31, 2013 13:57
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mala/4683033 to your computer and use it in GitHub Desktop.
Save mala/4683033 to your computer and use it in GitHub Desktop.
UPnPの設定変更をFlashから行うやつって今でも出来んのかという話
http://www.gnucitizen.org/blog/hacking-the-interwebs/ や、この問題を取り上げてるブログ記事なんかで
Flashの仕様じゃー、とかバージョンアップしても直らないみたいなこと書かれてるのですが、
少なくとも現状、Flashで独自のリクエストヘッダ追加した上でのクロスドメインのPOSTリクエストはcrossdomain.xmlを要求するようになっています。
Flashの仕様なんでバージョンアップしても解消しないんだぜー、って書かれたままの記事が多くあるため
「えっ、そうなの?」という印象を受けてしまった。
この記事が書かれた頃には出来たようだけど、JavaScript使いからするとこの挙動は直感に反するもので、
Flashを使うことで「ユーザーの許可無く」「ブラウザ標準の機能で出来ること以上のことが出来ている」のがおかしい。
ブラウザの標準の機能で、クロスドメインでのFormポストはできるけど、カスタムヘッダを付加した上でのクロスドメインのFormポストは出来ない。
(クロスドメインFormポストに関しても本来ブラウザがもっと強い警告出していいと思ってるけど)
XMLHttpRequest level2 のクロスドメイン通信で独自のヘッダを追加する場合の挙動は
ユーザーが独自のヘッダを追加する場合には、このヘッダ送ろうとしてるけど平気かい?というのを事前にチェックするようになってる。
http://www.w3.org/TR/cors/ の preflight request を参照
特別な権限の要求(ユーザーの許可 or サイト側での許可) が無しに、ブラウザで元々できていた程度のこと以上のことが
可能になってしまうようなプラグインの設計は、よろしくないと考えるべきだ。それは何らかのセキュリティ機構をぶっ壊すことになる。
なので、そういう穴があるんなら塞いだほうがいいし、UPnPに関してはブラウザで悪意のあるURLを開いただけ、では無理で
「もうちょい強い権限を持つアプリケーションからじゃないと変更できない」と考えてよさそうだ。
(できるようならユーザーの許可無くそういうことができちゃうブラウザのプラグイン側にも問題がある)
もっとも「UPnPで出来ちゃう設定変更がどこまでなのか」とか「使ってるルーターの脆弱性」によっては、
任意のホストに対してHTTPアクセスとかUDPパケット送信なんかが「思いのほか強い権限を持っている」ということにはなる。
元々ブラウザで出来ることしか出来ないんだったら、プラグインの意味が無いので、そりゃもちろん、機能は追加されるわけなのですが、
拡張機能などでブラウザに何かしらの機能を付け足す場合にも、同様のことを意識するといいんじゃないかと思います。
----
それはそうとしてcrossdomain.xmlの仕組み自体は安全ではない。
DNSリバインディングの類の攻撃に対して安全な実装が難しい。
evil.example.com/crossdomain.xml にアクセスしてクロスドメイン通信オッケーと判断した後に
evil.example.com の指し示すIPアドレスが変わってしまうようなケースだ。
まあそんなわけなのでクロスドメインリクエスト通して良いのかどうかは、リソース単位で分かったほうがよい。
----
検証用のコードはこんな感じ
// こんなん作って as3compile crosspost.as して 127.0.0.1:5000/crosspost.swf でアクセス
// 127.0.0.1:5000 -> localhost:5000 成功する
package {
import flash.display.MovieClip
import flash.net.*
public class Main extends MovieClip {
function Main(){
var r:URLRequest = new URLRequest('http://localhost:5000/');
r.method = 'POST';
r.data = 'hoge';
r.contentType = 'application/xml';
sendToURL(r);
}
}
}
// 今度はリクエストヘッダ付加
// 127.0.0.1:5000 -> localhost:5000 crossdomain.xmlを要求
// localhost:5000 -> localhost:5000 成功
package {
import flash.display.MovieClip
import flash.net.*
public class Main extends MovieClip {
function Main(){
var r:URLRequest = new URLRequest('http://localhost:5000/');
r.method = 'POST';
r.data = 'hoge';
r.contentType = 'application/xml';
r.requestHeaders.push(new URLRequestHeader('X-Hoge', 'hoge'));
sendToURL(r);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment