2011/08/19 (金)
Opera11.50 で https なのに「安全」と表示されないケース
opera | ![]()
javascript:void(open('http://www.google.co.jp/bookmarks/mark'))
window.open に http で渡すと、その後に https にリダイレクトされても「安全」マーク(なんて言えばいいんだろう?)が更新されないみたい。
まあリダイレクトされる前は安全じゃなかった(GETパラメーターが暗号化されていない)ので、そういうポリシーと思えなくも無いけど。
Opera について
バージョン情報
バージョン
11.50
Build
1074
まあ自分にとってはそれほど重要じゃないのでバグレポは後回し(しない、かなぁ)。
2011/06/23 (木)
Whac Dial という Opera Speed Dial Extension を作りました
Whac Dial は Speed Dial Extensions として動作する Opera の Extension です。現在(2011/06/24)はまだベータ版の Opera 11.50 以降で動作します。
--
--
ソースコードは github においています。
https://github.com/miya2000/whac-dial
https://github.com/miya2000/whac-dial/wiki
いい加減な英語なので、添削してもらえるとうれしいです...
Speed Dial Extensions って?
Speed Dial Extensions と言うのは Opera 11.50 からの新機能です。
これまでスピードダイヤルはページのスクリーンショット(静止画)を表示するだけでしたが、これを拡張することができるようになりました。
すでにOpera Speed Dial Extensions で JSNES がうごいたよーでも紹介しているように、表示をアニメーションすることが出来ます。
最近のブログパーツによくある、Twitter のタイムラインをつらつらアニメーションさせて表示したり、デジタルフォトフレームみたいな使い方が出来そうですね。
どういう風に作るかというと、実は通常の Opera Extension と全く同じで、スピードダイヤルにはバックグラウンドページをそのまま表示する形で実装されています。
Whac Dial について
インストール方法や使い方はgithub に書いた紹介ページを参照していただくことにして、Whac Dial の概要とコンセプトについてお話します。
Whac Dial はもう見たまんま、パックマンのゴーストがモグラ役のもぐら叩きです。
ただ、ゲームだけだとスピードダイヤルにする意味が薄いので、タイトルやクリックしたときのジャンプ先を自由に変えることが出来るようにしています。
さて、Whac Dial の作成において、以下のような意味付けを行いました。
スピードダイヤル拡張でインタラクティブなことが出来るかどうかの実験
スピードダイヤル画面から拡張に対してイベントを送ることは出来ませんから、これはもうはっきり言って出来ません。
クリックするとページに飛んじゃいますし、どの部分をクリックされたかもわかりませんから、マインスイーパとか無理。
で、それでも何かできないかなーということで、「スピードダイヤルで開いたページから最速でメッセージを返せば、スピードダイヤルのクリックを検知できそうだ」というのを思いつきました。
(Whac Dial v1.1 と Build 1073 では Opera の仕様変更のために検知できていません。Whac Dial v1.2 は現在申請中です。)
--
2011/06/28 v1.3 がダウンロードできるようになりました。
--
おそらくこれ以上のことは現状出来ないと思います。
スピードダイヤルをクリックする価値の創出
そもそもスピードダイヤルはリンク先のページに飛ぶためのものなので、あんな小さな窓に情報を詰め込むような拡張を作るより、クリックしたくなるような仕掛けを作りたいと思いました。
そいうわけで「特定のタイミングでクリックするといいことがある」ものとして、もぐらたたきをやってみようということになりました。
HTML5 機能を使ったリファレンス実装
僕はまだ Opera 10.10 を使っているのですが、Extension がブラウザと Cookie を共有するようになったこともあり、そろそろ移行したいなと思っています。
で、最新の Opera で出来ることををふんだんに取り入れてみました。
- CSS3
角丸・グラデーション・アニメーション・トランスフォーム・段組など。 - SVG
なめらかなアニメーションや JavaScript による制御。画面の大きさにあわせてスケーラブルになるようにしたり。 - MessageChannel による通信
SVGと通信してます。 - data-* アトリビュートや placeholder などの HTML5 新要素・新属性
特に SVG については、いい感触を持ちました。
SVG は Inkscape を使って(単純な絵とはいえ)簡単に書くことが出来ました(アニメーションの部分は Inkscape は対応していないので全て手書きですが)。
HTML5 といえば Canvas が推されているように見えますが、スケーラブルという点で非常に強力な選択肢の一つだと思います。
あと、とてもシンプルな xeyes を実装していて、拡大・縮小によって変換された座標と実際の座標(マウスの位置)との座標変換のサンプルになると思います。
extra url について
設定画面で「extra url」というのがあって、これに url を入力することで任意のページを Whac Dial の変わりにスピードダイヤルに表示することが出来ます。
これを使えば前に僕が作った Opera Image Dial Generator と同じこと(スピードダイヤルを好きな画像に差し替える)ができます。
ただ、それと違うのは最初に言ったようにアニメーションが出来ること。つまりはですね、紹介ページにも書いてますが、Whac Dial の gohst.svg をいじってここに設定すれば、自分の好きなキャラクターでもぐらたたきができちゃうんです! (もぐらたたきじゃなくてもいいけど)
何か作ったら教えていただけるとうれしいです。
あとがき
パックマンのキャラクターにしたのは、頭の中のイメージと合致したのと、なんといっても書きやすかったから。
キャラクターの使用については許可をとっていません。仮に申請しても現状は個人に対しては許諾しないとのことです。
法律で認められている場合を除き、弊社の許可なく下記に掲げます行為をなすことはできませんのでご注意ください。
なお、弊社は現状個人様に対する許諾を行っておりません(ホームページへの転載や掲載物を利用して新たな作品を作ることなども含みます)。
http://www.bandainamcogames.co.jp/info/
そういうわけで、「HTML5 でゲームを作成するための引用」という方向で行きたいと思います。
もちろん問題があればキャラクターの差し替えをしますので、その場合はご連絡ください。
それから Speed Dial Extensions のコンテストのTeam Upコンテストの締め切りに間に合うように作ったのだけど、コメントでやり取りしたわけじゃないし、参加表明をしたわけでもないし、審査対象になるのですかね?
(実はけっこう自信があったのだけど、まだレートが1人からしかもらえてない...)
2011/06/03 (金)
スクロールバーを消すと気持ちがよくなくなったのでバグレポ
opera | ![]()
--
DSK-338538
--
What kind of problem is this? *
Other problem
Where is the problem?
Web page problem
Brief summary of the problem encountered *
It becomes impossible to wheel scroll in 'overflow: hidden' element
What URL triggers this bug, if any?
http://orera.g.hatena.ne.jp/miya2000/20100516/p0
Describe in 3 steps or more how to reproduce this bug *
wheel scroll in 'overflow: hidden' element.
When following the steps described above:
1. What do you expect to happen? *
scroll if scrollHeight > clientHeight.
2. What actually happens? *
no scroll.
Optionally, provide an e-mail address where we can contact you
@miya2000
Fields marked with * are required.
Adding Files to Your Bug Report
On the next page you will be given an e-mail address which is unique to your bug. You can attach files (screenshots, test cases, crash logs) to your bug by sending them to this e-mail address.
The following information was auto-detected by Opera. We ask that you submit this as-is, but please update the Opera version number if the bug was not encountered in the browser you are currently using.
Specify what version of Opera you are using:
11.50 for Windows7 on the PC platform
If you know what build of Opera you are using, specify it here.
1031
--
Opera のバグレポは無視された感が半端無いのでもう2度とするまいと思ったはずなのに。。。
2011/05/19 (木)
Opera9.6 から「安全でなくなった」 UserJavaScript があるけどイコール「危険」というわけでもない話
何を主張したいのか良くわからないタイトルだけど、以下のような話をします。
- 発端となる Opera9.6 の変更
- どんな UserJavaScript が「安全でない」か
- どんなリスクがあるか
- でも「危険」というわけでもないケースが多い
- @include の仕様と、できるだけ安全にするためのTips
- 特権コードを使う UserJavaScript はすべからく extension に移行すべき(審議中)
--
発端となる Opera9.6 の変更
d:id:os0x:20081120:1227165925 で2008年11月に既に紹介されているように、Function に caller プロパティが追加されました。
Function.caller
9.60 beta 1 RCからFunctionにcallerプロパティが追加され、関数の呼び出し元を参照できるようになりました。
arguments.callee.caller で UserJavaScriptのソース取得 - 0xFF
このプロパティから、Function の呼び出し元の Function を取得することが出来ます。
function hoge() { alert(hoge.caller); } hoge(); // null (グローバル領域で実行した場合) (function aa() { hoge(); })(); // function aa() { hoge(); }
これは JavaScript の機能追加であって、一般的な JavaScript 処理系で問題が起こることはありません。
ですが Opera の UserJavaScript ではページ側の script と UserJavaScript 側で同じ Object(window や document、その他全てのビルトインオブジェクト) を共用しているため、ページ側の script では許されていない特権的な処理をUserJavaScript でやっていると、ページ側の script からそれらのオブジェクトを経由して、その特権的な処理を乗っ取ることが出来てしまいます(回避方法はありますがここでは触れません)。
// UserJavaScript でクロスドメイン通信を行う function function xGet(url, callback) { var s = document.createElement('script'); ... snip ... }
// ページ側から document.createElement を書き換えることで UserJavaScript の xGet を取得する。 var evilXGet = null; var _org_createElement = document.createElement; document.createElement = function(){ if (!evilXGet && /xGet/.test(arguments.callee.caller)) { evilXGet = arguments.callee.caller; document.createElement = _org_createElement; } if (evilXGet) { // ためしに Google トップページを取得。 evilXGet('http://www.google.co.jp/', function(txt) { alert(txt.substring(0, 200)) }); } return _org_createElement.apply(document, arguments); }
Opera の UserJavaScript と同様な機能を提供する Firefox のアドインの GreaseMonkey では、window や ビルトインオブジェクトは全て別のオブジェクトに置き換えられ(ラップされ)ていて、使い方を間違えなければ安全に GM_xmlhttpRequest などの特権コードを使うことが出来ます。
どんな UserJavaScript が「安全でない」か
まず、ほとんどの UserJavaScript は安全です。
UserJavaScript はもともと「Opera というマイナーブラウザでうまく動かない(表示できない)WEBサイトを閲覧者側で何とかする」という目的で導入されました。( ユーザー JavaScript にて使用可能なメソッドとイベント の API 郡から推測。)
ですから、ページ側の script で出来ること以上のことは基本的にできないようになっています。
例えば以下のような UserJavaScript が考えられますが、どれもページ側の script でもできることなので安全です。
- はてブ数を表示する(img 要素を追加しているだけ)
- リファラが Google の検索結果だったらリファラから検索語を取得してページ内のその文字を強調表示する(リファラはページ側の script で取得可能。後は自ページの DOM を操作するだけ)。
- ニコニコ動画のどのページでもマイリストを操作する(同じオリジンのサーバーと通信)。
では「安全でない」とはどういったケースでしょうか。このエントリを書いている時点でわかっているのは以下の2ケースです。
- UserJavaScript 内にユーザーIDやパスフレーズなど、個人情報や特別な処理を行うための情報を直接記述している。(前述の d:id:os0x:20081120:1227165925 で指摘されているもの。)
- UserJavaScript固有の機能を利用して、別オリジンのサーバーと通信できるようにしている。(http://mattz.xii.jp/comment/60#comment-60 で id:edvakf が指摘しているもの。)
どんなリスクがあるか
UserJavaScript 内にユーザーIDやパスフレーズを直接記述した場合、それらが盗まれる危険性があります。
上記のような UserJavaScript は滅多に無いと思いますが、例としてあげるなら私の Auto Commit del.icio.us(紹介ページ) があります。
もしパスフレーズが盗まれると、悪意のページを開いただけで delicious にブックマークが追加されてしまいます。
このケースを見ただけではリスクはとても小さく見えますが、そのユーザーID/パスフレーズによって何が出来るかが、そのままリスクの大きさになります。
別オリジンのサーバーと通信する処理が乗っ取られると、あなたがログインしているWEBサイトのページがその悪意のページに読み取られることになります。
もっともシンプルな例を挙げると Google のトップページです。GMail にログインしていると右上にメールアドレスが表示されますよね。これが読み取られますから悪意のページからあなたの GMail アドレスがわかってしまいます。
最悪のケースでは、あなたがログインしているWEBサイトでパスワードの再入力無しにできることが、以下のシナリオで行われる可能性もあります。
- 何らかの処理(例えば退会処理)を行うページを読み取る。
- 読み取ったページのソースから、処理を行うためのパラメーター(ワンタイムトークン等)を取得する。
- 処理を行うURLに上記のパラメーターを含めてリクエストすると処理が完了する。
ただし、紹介したシナリオで、退会処理のように重要な処理が行えることはまずありません。
これは以下の理由によるものです。
でも「危険」というわけでもないケースが多い
「安全でない」 UserJavaScript がほとんど無いということは既にお話しましたが、さらに UserJavaScript が安全でなかったとしてもすなわち「危険」でもないということをお話します。
良識ある UserJavaScript の作者の方は、その UserJavaScript が実行されるページを @include で設定します。
// ==UserScript== // @name Name of UserJavaScript // @include http://www.google.com/search?* // @include http://www.google.co.jp/search?* // ==/UserScript==
この例では Google の検索結果のページでしかこの UserJavaScript が読み込まれないことを保障します。つまり上で散々危険性を煽った「悪意のページ」の所業ですが、この UserJavaScript においては Google にしか行うことが出来なくなります。
もちろん UserJavaScript の実行を許可しているページに XSS 脆弱性があったり、(https でないと)ページが改竄されたりすることが全くありえなくも無く、その場合は前提が崩れてしまいますが、その場合はもっとひどいことが起こっていますので、多くの人が使用する有名な UserJavaScript でない限りは攻撃対象として狙われることはないと思われます。
ですから、あなたが UserJavaScript を使用する場合、どのスクリプトに対しても1度、使用するかどうかを判断する必要があるでしょう。
- その UserJavaScript が「安全」(あなたが個人情報やパスワードを入力する必要が無い、別のWEBサイトと通信を行わない)かどうか。
- 「安全でない」場合、@include で適用されるWEBサイトを、前述のリスクを踏まえて信用するかどうか。
先に紹介した「Auto Commit del.icio.us」のケースでは、パスフレーズを盗めるページがまさに「del.icio.us」本体なので、「安全で無い」けれども「危険で無い」典型的な例ですね。
@include の仕様と、できるだけ安全にするためのTips
以前、こんなエントリを書きました。
こんなスクリプトを書いたんだけど、
// ==UserScript==
// @name script - prevent external script
// @description prevent external script by hostname of page.
// @include http://codezine.jp/
// ==/UserScript==
(function(){
window.opera.addEventListener('BeforeExternalScript',function(e){
e.preventDefault();
},false);
})();
これだと http://b.hatena.ne.jp/entry/http://codezine.jp/ なんかでも適用されて困った。
ユーザーJavaScript で @include する時は、他のURLを含むURLに注意 - m2O - チーム俺等
実はこの問題は既に改善されていて、
// @include http://codezine.jp/
この場合は文字通り「http://codezine.jp/」のトップページでしか動かなくなっています。
他のページでも適用するには以下のようにワイルドカードを使用します。
// @include http://codezine.jp/*
ただ、依然として問題は残っていて、ワイルドカードがホントに何でもアリなところです。
例えば、Google 検索と Google Map で使いたい場合、
// @include http://*.google.co.jp/*
のような指定をしてしまうと、http://www.evil.com/?.google.co.jp/ のような URL でも動いてしまいます。
以下のように、面倒でも後方にだけワイルドカードをつけるようにすると安全です。
// @include http://www.google.co.jp/* // @include http://map.google.co.jp/*
特権コードを使う UserJavaScript はすべからく extension に移行すべき
(審議中)
2011/05/05 (木)
Opera Speed Dial Extensions で JSNES がうごいたよー
opera | ![]()
そのままだと XMLHttpRequest で ROM を読み出すところで失敗していたので、BASE64 化して loadROM するようにしました。
<script type="text/javascript"> $(function() { var data = 'TkVTGgIBAQAAA...(snip)'; nes.loadRom(atob(data)); nes.start(); }); </script>
Youtube にアップロードしてみました。
録画と Youtube へのアップロードはこれを使いました。便利ですね。
--



問題なのはそれが意図された動作かどうかと言う点ですが。。。
ちなみにリロードすると「安全」になります。あと JavaScript からじゃなくブックマークやアドレス入力でも「安全」に。