投稿されたすべてのトピック

Firefox の新しいメモリツール

この記事は 2015 年 11 月 11 日にポストされた “Firefox’s New Memory Tool” の抄訳です。

Firefox Developer Edition 44 には、新しくメモリツールが追加されました。このツールを使うと、Web アプリケーションのメモリ使用状況について理解しやすくなります。特にリソースの制限の厳しいモバイル向けの Web サイトの開発者には有用でしょう。この強力なツールの使い方は、フリーランスのクリエイティブデザイナーであり、フランスの Mozilla コミュニティメンバーでもある Baptiste Kaenel の作成した動画をご覧ください:https://youtu.be/DJLoq5E5ww0

メモリツールはまずメモリのスナップショットをとります。その結果を様々な点でグループ分けし、ツリーや表形式で表示します。標準では “coarse type” でグルーピングしています。この設定では、メモリ上のものを次の 4 つに分類します。

  • オブジェクト:JavaScript のオブジェクト。[[Class]] 名によって、より細かくグループ分けされます
  • Scripts:Web アプリケーションによってロードされた JavaScript のソースコード。ここにはSpiderMonkey の JIT コンパイラである IonMonkey によって生成された実行可能なマシンコードも含まれます
  • String:Web アプリケーションが使用する、JavaScript の文字列です
  • その他:上記のいずれにも属さないものを表します

“coarse type” 以外には、”object class” と “internal type” でもグルーピング可能です。前者では JavaScript の [[Object]] クラスによってグルーピングを行い、後者ではそれらの C++ での型によって分類します。後者は特に Firefox のプラットフォーム開発を行う人にとって有用な機能でしょう。

また “allocation stack” というグルーピング方法も選べます。これはメモリパネルの上部にある「割り当てスタックを記録」にチェックを入れることで利用できます。これは割り当てスタックの記録を取ることによって、アプリケーションのパフォーマンスが低下するためです。その代わり、ヒープ領域上のものを JavaScript コード上の位置によってグループ化して確認できるようになります。他の設定とは異なり、JavaScript のソースコードとメモリ上の要素とを直接関連付けて確認できるようになります。

allocation stack によってグルーピングされている例

スナップショットはいくつも取ることができ、それぞれのスナップショットにはメモリの使用量が MB 単位で表示されます。これを見ることで、アプリケーションのメモリの使用量が時間に応じて増減する様子を確認できます。

メモリツールの詳細については、MDN のメモリツールのページをご覧ください。また私たちは皆さまからのフィードバックをおまちしています。ぜひ Firefox Developer Edition をダウンロードし、コメントを @FirefoxDevTools 宛ににツイートください。

Dan Callahan について

Mozilla の Developer Relation を担当するエンジニア。元 Mozilla Persona の開発者。

Dan Callahan による他の記事はこちら

Nick Fitzgerald について

Firefox の開発ツールと JavaScript エンジンである SpiderMonkey を担当。ソースマップの仕様策定者の一人で、ブログ fitzgeraldnick.com を不定期に更新中。IRC では fitzgen でコンタクト可能。

Nick Fitzgerald による他の記事はこちら

Developer Edition 47:ユーザエージェントの変更、ポップアップデバッグなど

Developer Edition 47 – User agent emulation, popup debugging and more の抄訳です。

今週 Firefox Developer Edition 47 がリリースされました。この記事に関連して Devtools reload add-on service worker tooling などのポストもあります。それぞれのトピックについては、そちらもぜひご参照下さい。この記事では、Developer Edition のその他の変更点についてまとめます。

ユーザエーエジェントの偽装

ユーザエージェントを変更できる機能が、レスポンシブデザインモードに追加されました。「Custom User Agent」にユーザエージェント名を入力するだけで、ユーザエージェントを変更できます。例えばモバイルブラウザのユーザエージェントを入力すれば、デスクトップでもスマートフォン向けサイトを見ることができます。

ユーザエージェントを変更している様子は、こちらのスクリーンキャストをご覧ください:

ユーザエージェントを変更するスクリーンキャスト

参照グラフの表示

前回のリリースで、ドミネータビューが追加されました。これはメモリを多く利用するアプリのデバッグを助けるツールでした。今回のリリースでは、これにパスパネルが追加されました。このパネルではノードがグラフとして表示され、その中の選択されたノードはガーベジコレクションの対象ではなくなります。この機能は、メモリリークのデバッグを行う際に有用です。詳細については、MDN の解説をご覧ください。

ドミンネータビューのパスパネル

コンソールでの複数行入力

コンソールでの複数行入力がよりやりやすくなりました。Enter キーを押すだけで、入力が終了しているかどうかをコンソールが自動判断します。継続入力があると判断した場合は、次の入力行が表示されます。複数行を入力するのか、1 行のみの入力なのかを機にすることなく、コマンドを入力できるようになりました。

ストレージインスペクタ

ストレージインスペクタが、キャッシュストレージをサポートしました。Service worker のデバッグ時に有用な機能です。Service Worker のデバッグに関しては Sole Penadés のブログポストをご覧ください。

またツールバーにある検索ボックスを利用して、表示するコンテンツをフィルタできるようにもなりました。フィルタしている様子は、こちらのスクリーンショットをご覧ください:
ストレージインスペクタで表示するコンテンツをフィルタしている様子

テーマの変更

ツールボックスの表示も改善しました。標準のタブを少し短くすることや、メモリツールに新しくアイコンを追加といった小さな変更に加えて、いくつかの大きな変更もあります。ライトテーマの一新がその代表例です。より見やすく、洗練されたルック & フィールとなりました。

新しいライトテーマを利用した例は次のスクリーンショットをご覧ください:

新しいライトテーマを利用している例

またデバッガの表示も更新しました。条件付きのブレークポイントは、スクリーンショットのようにオレンジ色で表示されるようになりました:

条件付きブレークポイントのハイライト表示例

ネットワークモニタのツールバーの位置も、画面上部に変更されました。これでよりアクセスしやくなり、他のツールとのデザイン上の一貫性も保たれるようになりました。

ネットワークモニタ。ツールバーが上部に移動している。

アドオン向け:ポップアップのデバッグ

WebExtensions のリリースに向けて、アドオンのデバッグを簡単にする機能を追加されつつあります。今回のリリースでは、ポップアップの調査を簡単に行うための機能が追加されました。この機能を利用すると、クリックしてもポップアップが消えないようにロックできるようになります。ブラウザツールボックスを起動し、右上にある 4 つの四角を持つアイコンをクリックすることで、ポップアップをロックできます。詳しくはこちらの記事をご覧ください。

また実際の利用例をこちらのスクリーンキャストでご覧いただけます:
Firefox 47: debugging popups in WebExtensions

その他の変更点

上記の変更点に加えて、ツールボックスに全般にわたって改善が行われています。特筆するべきものは、以下の 2 つです:

また、Firefox のマルチプロセス化の関係で、3D ビューが削除されました。この機能を利用されたい場合は、こちらのアドオンをご利用ください。

フォントインスペクタも、標準では無効化されるようになりました。将来的には再度有効化される予定ですが、現在のリリースで有効化するには、about:config で devtools.fontinspector.enabled の値を変更する必要があります。

Developer Edition のリリースに貢献いただいたみなさま、ありがとうございました!最新版をこちらからインストールして、フィードバックをお願いします。

Tim Nguyen について

Firefox の開発ツールのコントリビュータ。Web 開発と Web デザインに情熱を持つ。

Twitter アカウント

Tim Nguyen による他の記事

Firefox 47 サイト互換性情報

先週金曜日、Firefox 46 Beta と Firefox 47 Developer Edition (Aurora) がリリースされました。いつも通りサイト互換性情報を用意していますので、Web 開発者の皆さんは一読されることをお勧めします。

もし一覧に漏れや間違いがあるときは下のコメント欄でお知らせください。

Firefox 開発ツールを使った Service Workers と Push のデバッグ

原文: Debugging Service Workers and Push with Firefox DevTools on March 11, 2016 by Soledad Penadés

Firefox 44 で Web Push が利用可能になった ことに引き続き、Firefox Developer Edition 47 の開発ツールでは Service Workers と Push Notifications のコードをデバッグできるようになりました。

この記事で採り上げる機能はこちらのスクリーンキャストで説明されています。New Service Worker debugging tools in Firefox Developer Edition 47

文字で読むほうが好きな方はこのままお読みください!

about:debugging

Service Workers の動作は通常の Web Workers と同じではなく、そのライフサイクルも両者で異なります。そのため、開発ツールの デバッガ タブに Service Workers のコードと通常のスクリプトを一緒に表示させることはできません。

そこで、登録された Service Workers と Shared Workers をすべて集めたダッシュボードを新しく追加しました。amongst other debuggable items such as Add-ons.

デバッグを始めるには、まず新しいタブに about:debugging と入力し、画面左の Workers タブをクリックします。

about-debugging

このダッシュボードを開く別の方法として、ツールWeb 開発Service Workers の順にメニューをたどる、またはツールバーのメニューから 開発ツールService Workers の順にクリックする方法もあります(開発ツール がない場合は、ツールバーメニューの カスタマイズ を利用してください)。

service-worker-menu

toolbar-menu

ダッシュボードのリアルタイム更新

このダッシュボードを初めて開いた場合、Service WorkerShared Worker のセクションに「まだありません。」と表示されているはずです。これらのセクションは Worker の登録に合わせて自動的に更新されます。表示されるボタンも Worker の状態に合わせて変わり、Worker が実行中であれば Pushデバッグ が表示され、登録された Worker がアクティブでなければ Start だけが表示されます。

試してみましょう!ウィンドウで about:debugging を開き、別のウィンドウでは 簡単な Service Worker のデモ を開いてください。Service Worker が登録され、Service Worker のセクションに表示されるはずです。ダッシュボードをリロードする必要はありません!

Service Worker のデバッグ

Service Worker をデバッグするには、その Worker を実行している必要があります。Debug ボタンをクリックするか、まだ実行中でなければ Start をクリックしてください(その Service Worker が登録済で about:debugging のダッシュボードに表示されていることが必要です)。

すると Service Worker のコードが書かれた新しいウィンドウが開きます。ここで 通常のデバッグと同じことはすべて、例えばブレークポイントを設定したり、ステップ実行や変数の確認などを行うことができます。

pop-up-debugger

Push Notifications

Web Push API を用いているコードもデバッグすることができ、Service Worker の push イベントリスナの中にブレークポイントを設定することで実現できます。プッシュ通知を受信すると、デバッガがブレークポイントで停止します。

pop-up-debugger-breakpoint

とても使いやすい機能ですが、ネットワークが一時的に接続できない場合など、手元で解決できない理由によってプッシュ通知の到着が遅れる場合があります。しかし嬉しいことに、その Worker に対して Push ボタンを押すことで、こういった状況でも push イベントに依存したコードをテストすることができます。

このボタンを押すと push payload が送信され、その後 push イベントが間髪入れずに発火します。これにより、サーバからプッシュ通知が届くまで待つ必要がなくなり、開発時間を短くする ことができます。

Shared Workers のデバッグ

Shared Workers のデバッグもサポートされています。とはいえ、Service Workers のデバッグと異なるのは about:debugging で表示される場所が違うことぐらいです。

(キャッシュされた)リクエストのデバッグ

通常のネットワークに向けたリクエストと、Worker によってキャッシュされたリクエストとを見分けることも可能です。キャッシュされたリクエストの場合、転送量 の欄に表示されるのがデータ量ではなく Service Worker と表示されます。

network-highlighted

fetch イベントリスナの中にブレークポイントを設定することで、Service Workers が発行するリクエストに割り込んでデバッグすることが可能です。

fetch-event

デバッガがブレークポイントで停止した際に、変数リストの中にある event オブジェクトを確認することで、リクエストされた url や HTTP ヘッダなどを調べることができます。

まとめ

私たちが現在取り組んでいる新機能について、おおまかな説明ができたことと思います。

about:debugging に関するリファレンス は MDN で参照できます。Service Workers についてより詳しく知りたい場合は Service Worker の利用について や、素晴らしいデモと使用例が載っている Service Workers cookbook を確認するとよいでしょう。

ES6 In Depth: Arrow functions

これは2015年6月4日にJason Orendorff氏によって投稿されたES6 in Depthの翻訳です。

ES6 In Depth はECMAScript標準, ES6でjavascriptプログラミング言語に加えられた機能のシリーズです。

Arrowsは初期からJavascriptの一部とされて進められてきました。最初のJavaScriptチュートリアルは”インラインスクリプトをHTMLコメントで囲め”と助言していました。これはjavascriptをサポートしていないブラウザが誤ってjsのコードをテキストとして表示されるのを防ぐためです。あなたはこんなコードを書いたと思います。

<script language="javascript">
<!--
  document.bgColor = "brown";  // red
// -->
</script>

古いブラウザには2つのサポートしていないタグとコメントに見えます。新しいブラウザのみjsコードと解釈します。

この妙なハックのためには、あなたのブラウザのJavascriptエンジンで<!--という文字列を一行コメントとして扱える必要があります。ジョークじゃないです。これは当初から今日におけるまで言語の一部として寄り添っています。そして、インライン<script>だけではありません、JSのコードのどこでも動きます。さらにNode.jsでさえも動きます。

たまたまこのスタイルのコメントは初めてES6で標準化されました。しかしこれは今日話す内容のarrowではありません。

arrow sequence –>もまた一行コメントとして表示(解釈)されます。奇妙なことにHTML文字列では–>の”前”がコメントで、JSでは行の残り、–>”後”がコメントです。

これは奇妙です。このarrowは行の開始に現れた時のみコメントとして適用されます。これは他の文脈では–>はJSの演算子、”goes to”演算子として働きます!

function countdown(n) {
  while (n --> 0)  // "n goes to zero"
    alert(n);
  blastoff();
}

このコードは本当に動きます。ループはnが0になるまで回ります。これはES6標準ではありませんが、
少しの間違いとともに複数のおなじみの機能が入り込んでいます。あなたはこれがわかりますか?
普通、パズルの答えはStack Overflowで見つかります。
もちろんここにはイコール大なり、<=演算子もあります。多分あなたはJSコードのなかで画像のような矢印をもっと見つけることができます、しかし立ち止まって矢印が欠落していることを観察してみましょう。

<!-- single-line comment
--> “goes to” operator
<= less than or equal to
=> ???

 

=>では何が起こるのでしょうか?今日、その謎を解決していきましょう。

最初に、functionについて少し話しましょう。

Function表現はどこにでも

Javascriptの楽しい特徴として、あなたが関数を必要とした時、いつでも動いているコードの中でfunctionとタイプするだけでいいことです。

例としてあなたは、ブラウザにユーザーが特定のボタンをクリックした時、何をしたいか伝えたいとします。こんなコードを書きますよね?

$("#confetti-btn").click(

jQuery’s .click() は引数を一つ取ります:functionです。あなたはここにfunctionとタイプするだけで良いのです。

$("#confetti-btn").click(function (event) {
  playTrumpet();
  fireConfettiCannon();
});

このようなコードを書くことは私達にとってとても自然なことです。なのでJavascriptがこの種類のプログラミングをはやらせる前は、多くの言語はこの機能を持っていませんでした。もちろんLispはfunction表現を持っていますが、それはラムダ式と呼ばれるものです。1958年のことです。しかしC++やPython,C#やJavaは長い間この機能を持っていませんでした。

でももう違います。上記4つともラムダ式を持っています。新しい言語は普遍的に組み込まれたラムダ式(注:ビルドイン関数ではない)を持っています。そして以前のJSプログラマが作った大胆なライブラリは深くラムダ式に依存し、この機能の採用を広く助けました。

これはちょっと残念です。その後、上の4つの全ての言語に私はメンションをして JavaScriptのラムダは、消滅しました。

// A very simple function in six languages.
function (a) { return a &gt; 0; } // JS
[](int a) { return a &gt; 0; }  // C++
(lambda (a) (&gt; a 0))  ;; Lisp
lambda a: a &gt; 0  # Python
a =&gt; a &gt; 0  // C#
a -&gt; a &gt; 0  // Java

あなたの矢筒に新しい矢を

ES6はfunctionに新しい記法を導入しました。

// ES5
var selected = allJobs.filter(<strong>function (job) {
  return job.isSelected();
}</strong>);

// ES6
var selected = allJobs.filter(<strong>job =&gt; job.isSelected()</strong>);

あなたが引数が一つでSimpleな関数を必要とする時、新しいarrow function記法はIdentifier =&gt; Expressionと書くだけで済みます。
あなたはfunctionやreturnをスキップ出来ます。同様に、幾つかの括弧、中括弧、そしてセミコロンも。
個人的にこの機能は素晴らしい物だと思っています。 functionとタイプする必要がないことは私にとって重要です。なぜなら私は代わりにfunctoinとタイプしてしまい、戻って修正する必要があるからです。

複数の引数 (もしくは引数なし、可変長引数やデフォルト引数、 破壊的代入)を取るfunctionを書くためには、複数の引数を括弧で囲むことが必要です。

// ES5
var total = values.reduce(<strong>function (a, b) {
  return a + b;
}</strong>, 0);

// ES6
var total = values.reduce(<strong>(a, b) =&gt; a + b</strong>, 0);

私はこれをとても素晴らしい物だと思います。

Arrow functionは美しい機能的なツールと一緒に Underscore.js and Immutable。などのライブラリから提供されています。実際に、この例は全てES6で書かれている Immutable’s documentation に載っています。なのでこれら多くはすでにarrow functionを使っています。

not-so-functional settingsとは?Arrow functionはexpressionの代わりにstatementsのブロック含むことが出来ます。以前の例を思い出して下さい。

// ES5
$("#confetti-btn").click(<strong>function (event)</strong> {
  playTrumpet();
  fireConfettiCannon();
});

ES6ではこのようになります。

// ES6
$("#confetti-btn").click(<strong>event =&gt;</strong> {
  playTrumpet();
  fireConfettiCannon();
});

わずかな改善です。このコードの効果は Promises を使用するともっと劇的に上昇します、 }).then(function (result) {のようなラインを重ね合わせることが出来ます

ブロック付きarrow functionは自動で値を返さないことに注意して下さい。その場合はreturn文を使用します。

arrow functionを使用しplainなオブジェクトを作る時に警告があります。オブジェクトは括弧で囲まなければいけません。

// create a new empty object for each puppy to play with
var chewToys = puppies.map(puppy =&gt; {});   // BUG!
var chewToys = puppies.map(puppy =&gt; ({})); // ok
//訳者解説:引数を取らず、ブロックステートメント({})を使わずにplainなオブジェクトを返す時のコードは括弧が必要です。

不幸にも、空のオブジェクト{} と空のブロック {}はちょうど同じです。ES6のルールに{arrowの直後にある{はブロックの開始として扱われる、オブジェクトで始まってはいけないという物があります。したがってpuppy => {}というコードはundefinedを返すarrow functionとして静的にインタプリタされます。

さらに混乱させるのが、{key:vaue}のようなオブジェクトリテラルはlabelを含んだブロックステートメントと同じということです。これはあなたのJSエンジンにはどのように見えるでしょうか?幸運にも{は曖昧な文字ですなのでオブジェクトリテラルを括弧で囲むというトリックを覚えておくだけで通用します。

Thisって何?(原文:What’s this?)

従来のfunctionとarrow functionには微妙な違いが存在します。Arrow functionは自分自身のthisを持ちません!arrow function内の値thisはいつもその外側のスコープの値を継承します。

試して実際に何を意味するのか理解する前に、すこし復習してみましょう。

JavaScriptでthisはどのように動作する?この値はどこから来てるの?この疑問を短い答えで返すことは出来ません。もしこの答えが頭のなかで出せるなら、それはあなたが長い間thisと一緒にいたからでしょう!

この疑問の理由はだいたいfunction functionがthisの値を自動で受け取ることに由来します。あなたはこんなハックを書いたことがありますか?

{
  ...
  addAll: function addAll(pieces) {
    var self = this;
    _.each(pieces, function (piece) {
      self.add(piece);
    });
  },
  ...
}

ほら、あなたが内部関数に書けばいいものはthis.add(piece)だけです。不運にも、内部関数は外部のfunctionのthisの値を継承しません。inner functionの内部ではthisはwindowやundefinedです。一時的な値selfは外側の値thisを内部に密輸します。(他の方法としてはbindを内部関数に使う方法があります。どちらの方法も綺麗です)

ES6ではもしあなたが下のルールを使用しているならだいたいthisハックは必要ありません。

  • object.method()記法を使って呼ばれるメソッドでnon-arrow function(いわゆるレキシカルなfunction)を使用している。これらのfunctionは意味のあるthisをcallerから受け取ります。
  • それ以外ではarrow functionを使用している。
// ES6
{
  ...
  addAll: function addAll(pieces) {
    _.each(pieces, piece =&gt; this.add(piece));
  },
  ...
}

ES6バージョンではaddAllメソッドはthisをcaller(function.caller)から受け取ります。内部関数はarrow functionです、なのでthisを外部のスコープから継承します。

ボーナスとしてES6はオブジェクトリテラルのメソッドを短く書く方法が提供されます!なのでこのコードは更にシンプルにすることが出来ます。

// ES6 with method syntax
{
  ...
  addAll(pieces) {
    _.each(pieces, piece =&gt; this.add(piece));
  },
  ...
}

メソッドとarrowsの間では、私は”functoin”と書くことはもうないと思います、これはいい考えです。

それらは arrow と non-arrow functionsのもっとマイナーな違いとしてarrow functionは自分自身のargumentsを受け取りません。

もちろん、ES6ではあなたは多分デフォルト引数や可変長引数を使用することでしょう。

Using arrows to pierce the dark heart of computer science

私達はarrow functionの実践的な使用方法について話してきました。これらのもっといろんなユースケース:ES6のarrow functionのlearning toolとして、計算科学の深いところまで話そうかと思います。あなたが参加するかどうかはアナタ次第です。

1936年にAlonzo ChurchとAlan Turingは独自で強力な計算モデルを開発しました。Turing はa-machinesと呼びました。しかし、人々はすぐにこのモデルをチューリングマシンと呼び始めました。Churchは代わりにfunctionについて書きました。彼のモデルは λ-calculus.と呼ばれています。この成果はLispでLAMBDAという文字が使われているのに由来します。

しかしラムダ式とは何でしょうか?計算モデルとは何を意味するのでしょう?

これを幾つかの言葉で説明するのは難しいですが、挑戦してみました:ラムダ式は最初のプログラミング言語です。これはプログラミング言語として設計されていません。_結局、10、20年経ってもプログラム内蔵コンピューターは来ませんでした。_しかし、あなたがやりたいと願った全ての計算の表現出来る言語はこれ以上無いほどSimpleで、必要最小限の、純粋な数学的アイデアです。Churchはcomputation in generalを証明するためにこのモデルが必要でした。

そして彼は彼のシステムにおいてfunctionのみが必要とされることを発見しました。

彼の主張がいかに特別だったかがわかります。オブジェクトなし、配列なし、数字なし、if文もwhileループもセミコロンもassignmentも、論理式もイベントループもです。これは全てのJavascriptが出来る全ての種類の計算をfunctionのみを使用して一から設計することが可能です。

これがChurchのラムダ式表記法を使い数学者が書くことが出来るタイプの”プログラム”の例です

fix = λf.(λx.f(λv.x(x)(v)))(λx.f(λv.x(x)(v)))

これと同等のJavascriptのfunctionです。

var fix = f => (x => f(v => x(x)(v)))
               (x => f(v => x(x)(v)));

これはJavaScriptにはλ-calculusの実装が含まれていて実際に実行できます。JavaScriptのラムダ式です。

このAlonzo Churchとその後の研究者がラムダ式で何をしたか、そしてそれがどのように大抵のメジャーなプログラミング言語に入り込む(実装される)かはこのブログの範囲を超えてしまいます。 しかしもしあなたがコンピューターサイエンスの基版に興味があるなら、 もしくはあなたがちょうどfunctionのみでループや再帰のようなこと出来る言語を見たいなら、あなたは 雨の午後を費やして、 Church numerals and fixed-point combinatorsを探して、あなたのFirefoxコンソールや Scratchpadで試すことが出来ます。ES6のarrowsの他の強みとともに。 JavaScriptはラムダ式を研究するための最良の言語です。

いつArrowを使えるの?

firefoxにおけるES6のarrow functionsは私が実装しました 。2013年頃です。 Jan de Mooijは実装を早くしてくれました。 パッチを投げてくださったTooru Fujisawa氏とziyunfei氏に感謝します。

Arrow functionsはMicrosoft Edgeのプレビューリリースでも実装されています。もしarrowをWebで使うことに興味があり、今すぐ使いたいなら BabelTraceurTypeScriptを使うことが出来ます。

次のトピックはES6の中でも奇妙なものです。typeof x が全く新しい値を返してきます。私達は尋ねます。なぜこれはstringじゃないの?私達は”同じ”の意味に悩むでしょう。これらは奇妙です。次の週は私達と一緒にES6のシンボルについて見ていきましょう。

DevTools Reload へのイントロダクション

原文: Introducing DevTools Reload on February 24, 2016 by Soledad Penadés

より多くの OSS 開発者が Firefox 開発ツールにコントリビュートできるよう、DevTools チームは DevTools Reload をリリースしました。DevTools Reload とは、開発に参加しようとした際にありがちなハードルを取り除くアドオンです。

成熟したオープンソースプロジェクトが巨大なコードベースを抱えているのは珍しくありません。しかしこれは、新しいコントリビュータが参加する際にハードルとなってしまう場合があります。コードが大量にあることで、理解するには長い時間が必要なのではと思うかもしれませんし、最初の一歩としては単純なバグ修正がベストであったとしても、巨大なコードベースのせいでタスクが難しく感じられてしまうかもしれません。

巨大なコードベースに起因するもう一つの欠点は、ダウンロードとコンパイルに多大な時間がかかってしまいがちであることです。これによって、新しいコントリビュータの参加をさらに妨げてしまいます。たとえダウンロードに成功できた場合でも、単純な変更を加えた後に再びコンパイルし直す際に長い時間がかかるため、忍耐力のある開発者でさえも気が滅入ってしまうのが大半でしょう。

DevTools Reload を利用すると、開発者が JavaScript と CSS のソースファイルに変更を加えられるようになります。そして、ショートカットキーを押すだけで 加えた変更すべてを自動的に開発ツールへ反映させることができます。これによって、開発ツールを Web と同じようにハックできるはずだと考えています。

このアプローチならば Firefox 開発ツールに単純な変更を加えやすいうえ、変更を加えている開発者に対してほぼ即座にフィードバックすることができ、思いついた解決策を検証して他の解決策を生み出すサイクルが速く回るようになります。

ここで、Firefox Nightly にアドオンをインストールする方法と機能のデモを紹介する 短いスクリーンキャスト を用意しました。書き言葉のほうが好みであれば、初めの一歩 を紹介するガイドも用意されています。

この機能は とても新しい ため、現在も鋭意開発中です。したがって、機能を実際に使ってみると荒削りな部分や矛盾点が見つかるかもしれません。思った通りに動作しない箇所を見つけたら、ぜひ バグを報告 するか何らかの手段で ご連絡ください。詳しい更新情報は DevTools チームのアカウント (@firefoxdevtools) をフォローして確認できます。ぜひ Bugzilla を通じて開発ツールにコントリビュートしてください。

Firefox 46 アドオン互換性情報

[これは Mozilla Add-ons Blog の記事 Add-on Compatibility for Firefox 46 の翻訳です]

Firefox 46 が 4 月 19 日 [日本時間同日深夜] リリース となります。Firefox 46 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 46 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。

一般

署名

新機能

この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 46 で動かなくなった場合は、筆者の方でも調査したいと思います。

AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので (Firefox 45 向けの更新もまだ保留となっています)、AMO に Firefox 45 対応のアドオンを登録している方は後日メールをチェックしてみてください。

Content Security Policy の導入

原文: Implementing Content Security Policy on February 16, 2016 by April King, Stuart Colville

Mozilla のアドオンチームは、addons.mozilla.org (AMO) で Content  Security Policy (CSP) を有効にする作業を終えました。この記事では CSP 導入時の基礎とともに、CSP を AMO へ導入した際に遭遇した問題点も紹介します。

Content Security Policy について

Content Security Policy (CSP) とは、クロスサイトスクリプティング (XSS) といったコンテンツを差し込む攻撃に関して、これらの攻撃に対する耐性を高めるためのセキュリティスタンダードです。CSP では、ユーザエージェントがコンテンツを取得する際の読込元を Web サイトの管理者が指定・制限し、先ほどの攻撃を防ぐという目的を達成します。

ポリシーはサーバからのレスポンスヘッダに指定します。そのポリシーをユーザエージェントが受け取り、ポリシーへの違反を検知して能動的にブロックします。ただし、サポートしているユーザエージェントによってその動作は異なります。

CSP が必要な理由

CSP は防御策に追加するレイヤーであり、XSS といったコンテンツを差し込む攻撃からユーザを保護するのに役立ちます。CSP は銀の弾丸でありませんが、攻撃者がコンテンツを差し込んだり、データを窃取したりするのはかなり困難となります。

Web サイトを安全に構築するのは難しいものです。Web セキュリティのベストプラクティスを広く知っていても何かを見落とすことはあり、安全だった Web サイトにうっかりセキュリティホールを導入してしまうのは非常に簡単です。

CSP は能動的・受動的なコンテンツの読込元オリジンを制限することで動作します。そのうえ、インライン JavaScript の実行や eval() の利用など、能動的なコンテンツの特性を制限することも可能です。

CSP の導入

CSP を導入するには、Web サイトが利用するすべてのリソースについて、許可したいオリジンのリストを定義する必要があります。例として、スクリプトとスタイルシートと画像がローカルでホストされており、CDN から jQuery ライブラリを読み込むシンプルな Web サイトを考えると、ポリシーは次のようになります。

Content-Security-Policy:
    default-src 'self';
    script-src 'self' https://code.jquery.com;

上記の例では HTTP ヘッダに Content-Security-Policy を指定していますが、Content-Security-Policy-Report-Only ヘッダを指定することも可能です。このヘッダを指定すると、ユーザエージェントはエラーを報告しますが、能動的にブロックすることはしません。新しいポリシーを検証する際に有効にしておくと便利な機能です。

補足: script-src にも 'self' を明示的に指定する必要があります。すなわち、ディレクティブを定義しても default-src を継承することはありません。

default-src を常に定義することはとても重要です。定義されなかった場合、他のディレクティブですべてのリソースが許可されてしまう可能性があります。default-src 'self' を指定すると、画像の読込元として Web サイト自身のドメインも許可されます。

default-src は特別なディレクティブであり、読込元が設定されていない他のディレクティブのフォールバックに利用されます。しかし、以下のディレクティブは default-src を継承しないため注意が必要です。以下のディレクティブに値を設定しなかった場合、単に値がセットされていないか、ブラウザのデフォルト設定が使用されるものと解釈されます。

  • base-uri
  • form-action
  • frame-ancestors
  • plugin-types
  • report-uri
  • sandbox

default-srcself を指定しても、自分の管理するドメインを指すので常に安全です。とはいえ、デフォルト設定をより強固なものにしたい場合は、default-src 'none' を利用し、既知のリソースタイプをすべて書き下すことも可能です。上記の例に当てはめると、ポリシーは次のようになります。

Content-Security-Policy:
    default-src 'none';
    img-src 'self';
    script-src 'self' https://code.jquery.com;
    style-src 'self';

補足: Web サイト上で prefetch を使用している場合、default-src 'none' によって問題が生じる可能性があります。AMO へ CSP を導入する際、prefetch されたリソースのコンテンツタイプが Firefox で認識されず、default-src にフォールバックしてしまう事象が見つかりました。このとき、Web サイトに必要なオリジンが default-src でカバーされていなければ、prefetch されたリソースはブロックされてしまいます。この問題に関する詳細は Bug 1242902 で公開されています

インラインスクリプトの扱い

明示的な指定のないデフォルトの CSP では、インラインの JavaScript が許可されません。すなわち、この場合では以下を取り除いておく必要があります。

  • ページ内の <script> ブロック
  • HTML 内の DOM イベントハンドラ(onclick など)
  • javascript: 疑似スキーム

これらを許可する必要がある場合は、ディレクティブの値に nonce-sourcehash-source を用いることで安全に実現できます。これらを利用すると、指定したブロック内のスクリプト実行を許可することができます。script-src ディレクティブに 'unsafe-inline' を指定すればこの保護を外すことも可能ですが、Web サイトが XSS 攻撃に脆弱になるため、'unsafe-inline' は利用しないことを強く推奨します。

nonce-sourcehash-source に関する詳細は CSP for the web we have(参考: 日本語訳)をご覧ください。

eval() の扱い

CSP では動的なスクリプト実行もブロックされ、以下が該当します。

  • eval()
  • setTimeout / setInterval の第 1 引数に渡す文字列
  • new Function() コンストラクタ

動的実行が必要ならば 'unsafe-eval' を利用することもできます。しかし、繰り返しになりますが 'unsafe-eval' の利用は推奨できません。なぜなら、eval ブロック内に信頼できないコードを差し込むことは容易だからです。

AMO への導入時、多くのライブラリで eval や new Function といったコードを利用していることが分かりました。この点は CSP の導入時に最も修正に時間がかかる部分です。例えば Underscore の template で new Function が使われており、修正策としてプリコンパイルした template を使用するよう変更しました。

カスケーディングスタイルシート (CSS) の扱い

デフォルトの CSP において以下は許可されません。

  • <style> ブロック
  • HTML 内の style 属性

これは支障が出ることがあります。多くのライブラリでは、JavaScript と一緒にページに追加された HTML スニペット内に style 属性を用いています。また、HTML テンプレートに直接 style 属性が使われることもあります。

説明を加えておくと、CSS スタイルのプロパティを直接 JavaScript で更新した場合は問題になりません。例えば、JQuery の css() メソッドは、スタイルのプロパティを直接更新するので大丈夫です。ただし、JS で追加された HTML ブロックに style="background: red" といった style 属性を用いることはできません。

補足: Firefox のインスペクタでは、JavaScript で追加されたスタイルのプロパティと HTML の style 属性は見分けがつきにくく、ほぼ同じように表示されます。

先程触れたように、部分的にインライン CSS を有効にしたい場合は、ディレクティブの値に nonce-sourcehash-source を使用できます。

もしかすると「CSS に何のリスクがあるんだ?」と思うかもしれません。実際、CSS を上手く用いて Web サイトからデータを窃取する方法が何通りもあります。例えば、属性セレクタと背景画像を用いることで、CSRF トークンのような機密データにブルートフォース攻撃を仕掛けて窃取することが可能です。この手法に関する詳細や、CSS を用いたより高度な他の攻撃ベクタについては XSS (No, the other ‘S’) を参照してください。

style-src'unsafe-inline' を設定することは推奨できません。しかし、インラインスタイルの除去に必要な変更の数とリスクのバランスを考慮する必要があります。

レポート機能

JSON 形式による CSP 違反レポートを集める場所を指定するには、report-uri ディレクティブで設定すると良いでしょう。現在の CSP にはエラーレポートをまとめる機能はないため、単一のページに複数のエラーがあった場合には、指定したエンドポイントに複数のレポートが送信されます。接続数が多い状態で Web サイトを稼働させてしまうと、報告先のエンドポイントには大量のトラフィックが流れ込んでしまいます。

実際の違反によって送信されたレポートに加え、多くのアドオンやブラウザ拡張が CSP に違反することにも気づくかと思います。全体的にノイズが大きくなるため、受信データにフィルタリングを行うことを強くおすすめします。

テスト

一番最初のポリシーを作成したら、次にポリシーをテストし、見落としているオリジンを修正します。大きな Web サイトを運用する場合、リソースの送信元が多いことに驚くかもしれません。CSP を適用した Web サイトを report-only モードで稼働させると、コンテンツを能動的にブロックしてしまう前に、コンソールと CSP レポートで問題点を把握できます。

コンテンツが誤ってブロックされていないことを確認できたら、いよいよポリシーを適用する段階です。これ以降は、見落としがないか注意することと、新しい CSP の機能をサポートしたブラウザに追随していくのみです。

適用

要件を満たすポリシーを適切に構築した後は、CSP ディレクティブを送信するようにシステムを設定する段階です。使用する Web サーバによって設定項目はかなり異なりますが、おおよそ次のようになるはずです。

# CSP を Apache で有効にする場合
Header set Content-Security-Policy "default-src 'none'; img-src 'self';
    script-src 'self' https://code.jquery.com; style-src 'self'"
# CSP を nginx で有効にする場合
add_header Content-Security-Policy "default-src 'none'; img-src 'self';
    script-src 'self' https://code.jquery.com; style-src 'self'";

Web サーバの設定を変更する権限がない場合でも心配ありません!CSP は meta タグでも有効にすることができ、<head> 内における最初の meta タグに CSP を有効にする旨を書くだけで大丈夫です。

<!-- ページの HTML 内で CSP を有効にする場合 -->
<head>
    <meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self';
          script-src 'self' https://code.jquery.com; style-src 'self'">
</head>

最後の適用作業

AMO はこれまでの運用期間が長く、かつ複雑度のかなり高い Web サイトであることを考えると、私たちが設計したポリシーの最終形に興味を持たれるかもしれません。実際には次のようになりました。

Content-Security-Policy:
    default-src 'self';
    connect-src 'self' https://sentry.prod.mozaws.net;
    font-src 'self' https://addons.cdn.mozilla.net;
    frame-src 'self' https://ic.paypal.com https://paypal.com
        https://www.google.com/recaptcha/ https://www.paypal.com;
    img-src 'self' data: blob: https://www.paypal.com https://ssl.google-analytics.com
        https://addons.cdn.mozilla.net https://static.addons.mozilla.net
        https://ssl.gstatic.com/ https://sentry.prod.mozaws.net;
    media-src https://videos.cdn.mozilla.net;
    object-src 'none';
    script-src 'self' https://addons.mozilla.org
        https://www.paypalobjects.com https://apis.google.com
        https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/
        https://ssl.google-analytics.com https://addons.cdn.mozilla.net;
    style-src 'self' 'unsafe-inline' https://addons.cdn.mozilla.net;
    report-uri /__cspreport__

これはすごいですね!容易に想像できる通り、かなり多くのテスト によって AMO の利用するリソースが無数に見つかりました。

まとめ

その Web サイトが運用されてきた期間が長いほど、妥当な Content Security Policy を設定するのには多くの時間がかかります。しかしながら、CSP は 多層防御 を構成する追加のセキュリティレイヤーにできるため、時間をかけてでも導入するだけの価値があります。

もっと詳しく

HTTP ページ上でのパスワード要求はやめましょう

[これは Mozilla のセキュリティエンジニア Tanvi Vyas 氏のブログ記事 No More Passwords over HTTP, Please! を同氏の許可を得て翻訳したものです]

Firefox 46 Developer Edition は、HTTP ページ上でログイン情報の入力を求められた場合、開発者に警告を行います。

ユーザ名とパスワードの組み合わせは、ユーザの個人データへのアクセスを管理する手段です。Web サイトはこうした情報を注意深く扱い、パスワードは HTTPS のような安全な (認証、暗号化された) 接続を通じてのみ要求すべきです。しかし残念なことに、HTTP のような安全でない接続でユーザのパスワードが扱われている例が 非常に多く 見られます。このプライバシーとセキュリティの脆弱性を開発者の皆さんに知らせるため、最新の Firefox Developer Edition で、安全でないページのセキュリティアイコンを赤い斜線の入った南京錠アイコンに変えることにより、問題を開発者に警告するようにしました。

Firefox 46 以降の Developer Edition では、パスワード入力欄を含む安全でないページ上で赤い斜線付きの南京錠が表示されます

Firefox はパスワード入力欄が安全かどうかをどうやって判断するのでしょうか?

Firefox は、パスワード入力欄が安全であるかどうかを、それが埋め込まれているページを調査することで判断します。各ページは、W3C の Secure Contexts 仕様 で定められたアルゴリズムに従って、安全かそうでないか確認されます。安全でないページに埋め込まれているあらゆる要素は 中間者 (MITM) 攻撃によって改ざんされる恐れがあります。攻撃者は、以下に挙げるような様々な仕組みを用いて、安全でないページ上で入力されたパスワードを抜き出すことが可能です。

  • フォームの action 属性を変更することで、本来の送信先ではなく攻撃者の管理下にあるサーバへ向けてパスワードが送信されるようにします。その後本来の送信先へ、その盗み取ったパスワードを転送するようにして、即座にリダイレクトします。
  • JavaScript を使って、フォーム送信前にパスワード入力欄の内容を取得し、それを攻撃者のサーバへ送信します。
  • JavaScript を使って、ユーザのキー入力操作を記録し、それを攻撃者のサーバへ送信します。

上記の攻撃はすべて、アカウント情報が漏洩したことにユーザが気付かないうちに起こり得るという点に注意が必要です。

Firefox は、バージョン 26 以降、開発者ツールの Web コンソール を通じてこの問題を開発者に警告しています。

なぜ HTTPS を通じてパスワードの送信するだけでは十分と言えないのでしょうか? なぜログインフォームの置かれたページまで HTTPS でなければいけないのでしょうか?

このような質問は頻繁に聞かれますので、この記事で特に取り上げなければと考えていました。HTTP の代わりに HTTPS を通じて送信を行えば、確かにネットワーク盗聴者がユーザのパスワードを覗き見るのを防ぐことは可能ですが、活動中の中間者攻撃者が安全でない HTTP ページからパスワードを抜き出すのを防ぐことはできません。上で説明した通り、活動中の攻撃者は Web サーバとユーザのコンピュータの間で HTTP 通信に割り込み、Web ページの内容を改ざんすることが可能です。攻撃者は、サイトがユーザへ届けようとした HTML の内容を取得し、ユーザ名とパスワードを盗み出す JavaScript をページへ追加した上で、そのページをユーザへ送りつけるといったことができてしまうのです。ユーザが自分のユーザ名とパスワードを入力すると、それは攻撃者と本来の送信先の両方へ送られることになります。

私のサイトでは認証情報がそれほど重要ではないのですが?

サイトへのアクセスにユーザ名とパスワードが必要とされるものの、さほど重要なデータは保存されていないという場合もあるでしょう。たとえば、あるニュースサイトで、ユーザが後で読みたい記事のリストが保存されている一方で、ユーザに関するその他のデータは一切保存されていないとしましょう。多くのユーザはこれを機密性の高い情報だとは考えません。そのサイトやユーザの認証情報を保護しなければいけないと、そのニュースサイトの Web 開発者が動機付けられる可能性も低いでしょう。しかしながら、パスワードの使い回しは大きな問題となっています。ユーザは、ニュースサイトから、ソーシャルネットワーク、Web メール、銀行まで、複数のサイトで同じパスワードを使っている可能性があります。そのため、たとえあなたのサイトでユーザ名やパスワードの漏洩が重大なリスクと見なされない場合でも、同じユーザ名とパスワードを使ってオンラインバンキングへログインしているユーザにとっては大きなリスクとなり得るのです。攻撃者はますます賢くなっており、あるサイトからユーザ名とパスワードの組み合わせを盗み出したら、より「儲かる」サイトで使い回そうと試みます。

私のサイトからこの警告をなくすには?

ログインフォームを HTTPS ページ上に置いてください。

もちろん、そのための一番単純な方法は、Web サイト全体を HTTPS へ移行することです。今すぐそれができない場合は、ログイン専用の HTTPS ページを別途用意してください。そして、ユーザがあなたのサイトへログインする際には、必ずその HTTPS ログインページへ誘導するようにしてください。フォームの送信先が HTTPS になっている場合、あなたのドメインの一部は既に HTTPS を使うよう作られているはずです。

HTTPS を通じてコンテンツを配信するには、認証局 から TLS 証明書 を取得する必要があります。Let’s Encrypt は無料で証明書を発行してくれる認証局です。サーバの設定方法に関しては、Mozilla WikiSSL Configuration Generator を参照してください。

ページが自分の管理下にない場合はどうすればいいのでしょうか?

Firefox Developer Edition のユーザが、自分の管理しているサイトを開発するためだけでなく、普段の Web ブラウジングにも Developer Edition を使っている場合があることは承知しています。自分の管理下にないページ上でこの警告を目にした開発者は、それでもいくつかの行動を取ることが可能です。自分のデータを守るために、ロケーションバーに表示されている URL の先頭に「https://」を追加し、安全な接続を通じてログインできるかどうか試してみましょう。また、サイトの管理者に連絡を取って、そのサイトが抱えているプライバシーとセキュリティの脆弱性について注意を呼びかけることもできるでしょう。

盗まれたパスワードが原因で発生した攻撃は実際にありますか?

パスワードの使い回しが大規模な情報漏洩につながった事件は、DropboxSonyLinkedInHBGaryAstrosYahoo! など、数多く報告されています。中間者攻撃によってログインフォームからパスワードが盗み出された被害はまだあまり知られていませんが、JavaScript インジェクションの基本的なテクニックは インターネットサービスプロバイダ政府機関 によって幅広く使われています。

ページ上にパスワード入力欄が見当たらない場合も時々この警告が表示されるのはなぜですか?

パスワード入力欄を最初から隠しておき、ユーザが何らかの操作を行うまで表示させないという手法が時々見られますが、そうしたページでもこの警告は表示されます。パスワード入力欄がページ上に表示されるタイミングをどう判別すべきかという バグ が登録されています。

この機能はベータ版やリリース版の Firefox ユーザも使えるようになりますか?

今のところ、この機能は開発者に主眼を置いています。なぜなら、ユーザのパスワードを危険にさらしているサイトを最終的に修正しなければならないのは、他でもない開発者の皆さんだからです。ただ、一般的に言って、私たちは長期的に 安全でない HTTP を廃止する 方向で動いているため、ブラウザが何か安全でないものを検知した場合に明示的な警告を目にする機会が増えていくことは十分に予想されます。たとえば、Firefox の現行版はいずれも、開発者ツールのネットワークモニタにおいて、安全でない HTTP 接続に関してはすべて 赤い斜線付きの南京錠アイコンを表示しています

Firefox の他のバージョンでこの警告を有効にするには?

Firefox 44 以降のユーザは、チャンネルを問わず、以下の手順でこの機能の有効、無効を切り替えられます。

  1. Firefox で新しいウィンドウまたはタブを開きます。
  2. ロケーションバーに about:config と入力し Enter キーを押します。
  3. 注意深く使うよう呼びかけるページが表示されますので、その通りにします。
  4. security.insecure_password.ui.enabled という設定の値が、Firefox が安全でないログインページについて警告するかどうかを決定します。値を true に切り替えれば、この機能が有効になり、安全でないログインページ上で警告が表示されるようになります。値を false に切り替えれば、この機能を無効化できます。

謝辞

この機能の実装とユーザ体験向上を担当してくれた Paolo Amadini、Aislinn Grigas 両氏にこの場を借りて特に感謝の気持ちを表したいと思います。

Firefox 45 アドオン互換性情報

[これは Mozilla Add-ons Blog の記事 Add-on Compatibility for Firefox 45 の翻訳です]

Firefox 45 が 3 月 8 日 [日本時間同日深夜] リリース となります。Firefox 45 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 45 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。

一般

UI

XPCOM

署名

新機能

  • 簡易 JSON アドオン更新プロトコルに対応しました。Firefox は、独自に自動更新を管理しているアドオンのために、既存 XML 形式の代わりとなる JSON 更新ファイル に対応しました。新しいアドオンについては JSON 形式の使用を推奨します。既存のアドオンについては、大半のユーザが 45 以降にアップグレードするまで切り替えるべきではありません。

この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 45 で動かなくなった場合は、筆者の方でも調査したいと思います。

AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので、AMO に Firefox 44 対応のアドオンを登録している方は後日メールをチェックしてみてください。