なぜクレジットカード番号やセキュリティコードが流出するのか

商品をクレジットカードで購入できるサイト(いわゆるネットショップ)には、当然、購入者の氏名や住所、メールアドレスなどの個人情報や、購入した商品の種類や個数、価格などの購入情報がデータベースに保存されていることが想像できます。しかし、普通はクレジットカード情報(クレジットカード番号、名義人、有効期限、セキュリティコードなど)はそのネットショップのデータベースには保存されていません。たとえ「次回購入のためにクレジットカード情報を保存する」のような機能を利用したとしても、そのネットショップのデータベースには保存されません。なぜなら、購入者が入力したクレジットカード情報は、ネットショップからそのままクレジットカード決済代行会社に送信されて決済が実施されるためです。クレジットカード決済代行会社は決済を実施したり、クレジットカード情報を保存するためのAPIを用意しています。ネットショップはそれらのAPIを利用すればよいので、クレジットカード情報を自社のデータベースに保存する必要がないのです。

にもかかわらず、世の中の個人情報流出のニュースを見ていると、氏名や住所やメールアドレスなどに加えてクレジットカード番号やセキュリティコードまで流出している例が見られます。このような事件が起きるたびに、SNSなどでは「なぜクレジットカード番号やセキュリティコードまで保存する仕様にしたのか」といった意見が聞かれますが、前述のような仕組みであれば、あえてクレジットカード情報を保存する仕様にしているとは考えにくいでしょう。では、なぜクレジットカード番号やセキュリティコードが流出してしまうのでしょうか。ありがちな「ログに残ってしまった」例を考えてみます。

※なお、ログに残る以外にも、クレジットカード情報入力画面が改ざんされて入力値が収集されてしまう手法なども考えられます。

決済時のログを記録している

バグの調査や購入者からの問い合わせに対応するために、決済時の情報をログとして記録している場合があるかと思います。以下はPHPの例です。

<?php
$params = array();
$params['card_number'] = $_POST['card_number'];
$params['card_holder'] = $_POST['card_holder'];
$params['card_expire'] = $_POST['card_expire'];
$params['card_securitycode'] = $_POST['card_security_code'];
$params['order_number'] = 注文番号;
$params['order_price'] = 注文金額;

// 決済代行会社のAPI呼び出し
$api->authorization($params);

// 後の調査のために決済時のパラメータをログに記録する
error_log(print_r($params, true), 3, 'log.txt');

この場合、当然log.txtが外部に流出するとクレジットカード情報が流出することになります。

エラーハンドラでログを記録している

決済時のログを明示的に記録していなくても、エラー時に自動的にログを記録する仕組みがあります。以下はPHPのエラーハンドラの例です。

<?php
set_error_handler(function($errno, $errstr, $errfile, $errline){
    // 後の調査のためにバックトレースをログに記録する
    error_log(print_r(debug_backtrace(), true), 3, 'log.txt');

    return true;
});

$params = array();
$params['card_number'] = $_POST['card_number'];
...

// 決済代行会社のAPI呼び出し
$api->authorization($params);

この場合、正常に処理が完了した場合は問題ありませんが、何かエラー(WarningやNoticeなども含む)が起きるとその内容が自動的にログに記録されます。バックトレースにはPOSTされた値などが含まれる可能性があるので、ログにクレジットカード情報が記録されてしまいます。

対策

クレジットカード情報をマスキングしてログに記録する

クレジットカード情報が記録されたログが流出してしまう場合を想定して、クレジットカード番号やセキュリティコードを ***** のような文字列に置換したり、消去したりしてログに記録するという方法が考えられます。

<?php
$params = array();
$params['card_number'] = $_POST['card_number'];
...

// 決済代行会社のAPI呼び出し
$api->authorization($params);

// 後の調査のために決済時のパラメータをログに記録する
unset($params['card_number']);
...
error_log(print_r($params, true), 3, 'log.txt');

ただし、この方法ではマスキングし忘れたり、エラーハンドラを利用する場合は正規表現などでマスキングする情報を特定しなければならず、対策が漏れやすい方法と言えます。

トークンによるクレジットカード決済に対応する

そもそも、クレジットカード情報をネットショップに送信しなければログにも残りません。経済産業省は「クレジットカード取引におけるセキュリティ対策の強化に向けた実行計画2017(「実行計画2017」)」というものを策定しており、この計画でネットショップはクレジットカード情報を保存することのみならず、「通過」させないことも強く推奨してます。つまり、クレジットカード情報をネットショップにGETPOSTで送信することすら危険なのでやめましょうということです。 www.meti.go.jp ではクレジットカード情報をネットショップに送信せずにどのように決済を実施するのかということになりますが、そこで登場するのが「トークン」です。購入者が入力したクレジットカード情報をJavaScriptによってトークン化し、そのトークンをネットショップからクレジットカード決済代行会社に送信することによって決済を実施します。

function pay() {
    getToken({
        'card_number': $('#card_number').val(),
        'card_holder': $('#card_holder').val(),
        ...
    }, callback);
}

function callback(response) {
    // トークンを取得する
    $('#card_token').val(response.token);

    // カード情報をサーバに送信しないように値をカラにする
    $('#card_number').val('');
    $('#card_holdeer').val('');
}

ネットショップのクレジットカード情報入力画面のHTMLソースをよく見ると、token.jsのようなJavaScriptファイルが読み込まれていることがあります。これはクレジットカード決済代行会社が提供しているトークン化のためのライブラリの可能性があります。

このように、クレジットカード情報を自社のデータベースに保存する仕様は論外ですが、それ以外にもログを通してクレジットカード情報が流出してしまう危険性があるため、ネットショップはトークンに対応したクレジットカード決済を導入することが強く推奨されています。購入者の立場からすると、トークンに対応していることが明示されていると安心度が増すのではないでしょうか。

PHP 7.2.0 Alpha 1をインストールして新機能を試してみる

PHP 7.2系の初めてのAlpha版である PHP 7.2.0 Alpha 1がリリースされました。

http://php.net/archive/2017.php#id2017-06-08-2

さっそくソースファイルからインストールして新機能を試してみます。なお、ここではWebサーバなどは使わず、単純にコマンドラインで実行を確認します。OS は VirtualBox 上の Ubuntu Server 16.04.2 LTS を使用し、必要なソフトウェアは、都度 apt でインストールしています。(例えば sudo apt install clang libxml2-dev make

まず、PHP 7.2.0 Alpha 1 のソースファイルを取得します。

$ wget https://downloads.php.net/~pollita/php-7.2.0alpha1.tar.gz

ダウンロードしたファイルを展開し、展開したディレクトリに移動します。

$ tar zxf php-7.2.0alpha1.tar.gz
$ cd php-7.2.0alpha1

ソースファイルからビルドします。今回は試すだけなので ./configure のオプションには特に何も指定していません。

$ ./configure
$ make
$ make test
$ sudo make install

sudo make install 時にPEARに関する次のようなエラーメッセージが表示されましたが、今回の試用には影響は無いのでそのまま進めます。

Makefile:445: ターゲット 'install-pear-installer' のレシピで失敗しました
make[1]: *** [install-pear-installer] エラー 255
Makefile:448: ターゲット 'install-pear' のレシピで失敗しました
make: *** [install-pear] エラー 2

インストールが完了すると php コマンドが利用できるようになります。

$ php -v
PHP 7.2.0alpha1 (cli) (built: Jun 10 2017 15:27:20) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0-dev, Copyright (c) 1998-2017 Zend Technologies

では、PHP 7.2.0 の新機能を試してみます。

オーバーライドされたメソッドの型宣言の省略

PHP 7.1 ではメソッドをオーバライドする際、親クラスと子クラスの引数の型宣言を同じものにする必要がありましたが、PHP 7.2 では子クラスの引数の型宣言を省略することができるようになりました。

<?php
class Foo
{
    public function hello(string $str)
    {
        echo "{$str} in Foo.\n";
    }
}

class Bar extends Foo
{
    // PHP 7.1 では public function hello(string $str) と書く必要がありました
    public function hello($str)
    {
        echo "{$str} in Bar.\n";
    }
}

$bar = new Bar();
$bar->hello('Hello, PHP 7.2');    // Hello, PHP 7.2 in Bar. を表示

これにより、今までは親クラスのメソッドに型宣言を追加すると、すべての子クラスのメソッドを変更しなければなりませんでしたが、 PHP 7.2 では子クラスをひとつずつ変更することができるので、変更作業を段階的に行うことができます。

抽象メソッドのオーバーライドを許可

抽象(abstract)メソッドをオーバーライドできるようになりました。

<?php
abstract class Foo
{
    abstract function bar(string $x);
}

abstract class Bar extends Foo 
{ 
    abstract function bar(string $x): int; 
}

名前空間のリスト構文で最後のカンマを許可

名前空間をグループ化してリスト状に書く場合、最後にカンマを書けるようになりました。

<?php
// PHP 7.1 では use Foo\Bar\{ Foo, Bar }; と書く必要がありました
use Foo\Bar\{ Foo, Bar, };

リストの最後にカンマを許可する提案は、関数の引数やクラスのメンバ変数などの他の構文でもあったようですが、投票の結果、採用されたのは名前空間グループ化(use)だけだったようです。 https://wiki.php.net/rfc/list-syntax-trailing-commas

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)

docs.hatenablog.jp

X-ChromeLogger-Dataヘッダを使うとWebブラウザのコンソールにログを出力できる

主なWebブラウザにはコンソール機能があるので、JavaScriptconsole.log('Hello, world.'); と書くとコンソールにログを出力することができます。

X-ChromeLogger-Data というHTTPヘッダを使うと、JavaScriptに限らず、サーバサイドのプログラミング言語からFirefoxのコンソールへログを出力することができます。次に示すのはPHPX-ChromeLogger-Dataヘッダを出力する例です。

<?php
$log = array();
$log[] = array(array('Hello, world.'), 'log');

$json = array(
    'columns' => array('log', 'type'),
    'rows' => $log
);
$data = base64_encode(utf8_encode(json_encode($json)));
header('X-ChromeLogger-Data: ' . $data);

FirefoxはこのHTTPヘッダを受け取ると、コンソールへデコードした文字列を出力します。

f:id:hontonodeai:20170109131354p:plain

出力するレベルは上記の例で示した log のほかに、infowarnerror を使うこともできます。

<?php
$log = array();
$log[] = array(array('Hello, world.'), 'log');    // ログレベルを出力
$log[] = array(array('Hello, world.'), 'info');   // メッセージレベルを出力
$log[] = array(array('Hello, world.'), 'warn');   // 警告レベルを出力
$log[] = array(array('Hello, world.'), 'error');  // エラーレベルを出力

なお、FirefoxX-ChromeLogger-Data をデフォルトでサポートしていますが、Chromeの場合はChrome Loggerという拡張機能をインストールする必要があります。

craig.is

Chrome Loggerでは各言語別のロギングライブラリも紹介しており、PHPのライブラリを使うと以下のように簡単に書くことができます。

<?php
include 'ChromePhp.php';
ChromePhp::log('Hello, world.');

X-ChromeLogger-Data はHTTPヘッダなので、XMLJSON、PDFなど、余計な文字列を出力するとフォーマットとして成り立たないデータを表示する場合でも気軽にデバッグに使えそうです。

PHPプログラムの複雑度をPHPMDで客観的に測定する

プログラムが複雑になると、テストケースが増大し、保守性が低くなることは直感的・経験的に理解できますが、この複雑度を客観的に測定する方法として循環的複雑度(Cyclomatic complexity)があります。PHPでは、PHPMDを使って循環的複雑度を測定することができます。

PHPMD - PHP Mess Detector

インストール

PHPMDをインストールする方法はいくつかありますが、ここでは簡単な phpmd.phar を利用する方法を紹介します。 phpmd.phar を利用するためには、最新版をダウンロードして実行権限を付与するだけです。

$ wget -c http://static.phpmd.org/php/latest/phpmd.phar -O phpmd
$ chmod +x phpmd

なお、 phpmd.phar を実行するためには php-bz2 が必要なので、インストールされていない場合はインストールしておきます。次に示すのは Ubuntu 16.04 で apt を使ってインストール例です。

$ sudo apt install php-bz2

以下を実行してPHPMDのバージョン情報が表示されることを確認します。

$ ./phpmd --version
PHPMD 2.5.0

複雑度の基準

それでは早速PHPMDで循環的複雑度を測ってみますが、その前に複雑度の基準について説明します。PHPMDのドキュメントによると、複雑度は以下のように分類されます。

数値 複雑度
1~4
5~7
8~10
11以上 非常に高い

https://phpmd.org/rules/codesize.html#cyclomaticcomplexity

デフォルトではPHPMDがレポートを出力する閾値は10となっているため、複雑度がそれより低い場合はレポートを出力しません。今回は確認のため複雑度が低くてもレポートを出力するようにPHPMDのルールセットを変更します。ルールセットを変更するには以下のようなXMLruleset.xml というファイル名で保存します。reportLevel を 1 に設定するのがポイントです。

<?xml version="1.0"?>
<ruleset
    xsi:nonamespaceschemalocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
    xsi:schemalocation="http://pmd.sf.net/ruleset/1.0.0
                        http://pmd.sf.net/ruleset_xml_schema.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://pmd.sf.net/ruleset/1.0.0"
    name="PHPMD rule set">
    <rule ref="rulesets/codesize.xml/CyclomaticComplexity">
        <properties>
            <property value="1" name="reportLevel"></property>
        </properties>
    </rule>
</ruleset>

プログラム例

それでは簡単なプログラムを書いてPHPMDを実行してみます。まずは次のようなプログラムを sample1.php というファイル名で保存します。

<?php
function sample1()
{
    echo "Hello, world.";
}

次のコマンドを実行します。

$ ./phpmd sample1.php text ruleset.xml
sample1.php:2  The function sample1() has a Cyclomatic Complexity of 1. The configured cyclomatic complexity threshold is 1.

Cyclomatic Complexity of 1 が出力されたので、循環的複雑度は 1 であることが確認できます。

次に、プログラムを少し複雑にしてみます。次のようなプログラムを sample2.php というファイル名で保存します。

<?php
function sample2($format)
{
    if ($format === 'xml' || $format === 'text' || $format === 'html') {
        echo "valid format.";
    } else {
        echo "invalid format.";
    }
}
$ ./phpmd sample2.php text ruleset.xml
sample2.php:2 The function sample2() has a Cyclomatic Complexity of 4. The configured cyclomatic complexity threshold is 1.

Cyclomatic Complexity of 4 が出力されたので、循環的複雑度は 4 であることが確認できます。

このプログラムを in_array() を使うように変更してみます。

<?php
function sample2($format)
{
    if (in_array($format, array('xml', 'text', 'html'), true)) {
        echo "valid format.";
    } else {
        echo "invalid format.";
    }
}
$ ./phpmd sample2.php text ruleset.xml
sample2.php:2 The function sample2() has a Cyclomatic Complexity of 2. The configured cyclomatic complexity threshold is 1.

循環的複雑度は 2 になりました。つまり、先ほどの in_array() を使わないバージョンより、 in_array() を使うバージョンの方が循環的複雑度が小さくなったことを意味します。

まとめ

循環的複雑度はあくまで指標のひとつです。循環的複雑度が小さいプログラムの可読性や効率が必ず高いとは限りません。しかしながら、プログラムの複雑度を計測することで、プログラムを変更した後の複雑度の変化を客観的に知ることができます。プログラミングの際に循環的複雑度を意識し、計測することで、よりよいソフトウェアを開発するためのヒントになるのではないでしょうか。

新装版 達人プログラマー 職人から名匠への道

新装版 達人プログラマー 職人から名匠への道

docs.hatenablog.jp

PHP 7.1.0 正式版をインストールして新機能を試してみる

PHP 7.1.0 正式版がリリースされました。

http://php.net/releases/7_1_0.php

さっそくソースファイルからインストールして新機能を試してみます。なお、ここではWebサーバなどは使わず、単純にコマンドラインで実行を確認します。OS は VirtualBox 上の Ubuntu Server 16.04.1 LTS を使用し、必要なソフトウェアは、都度 apt でインストールしています。(例えば sudo apt install clang libxml2-dev make

まず、PHP 7.1.0 のソースファイルを取得します。

$ wget -O php-7.1.0.tar.gz http://jp2.php.net/get/php-7.1.0.tar.gz/from/this/mirror

ダウンロードしたファイルを展開し、展開したディレクトリに移動します。

$ tar zxf php-7.1.0.tar.gz
$ cd php-7.1.0

ソースファイルからビルドします。今回は試すだけなので ./configure のオプションには特に何も指定していません。

$ ./configure
$ make
$ make test
$ sudo make install

インストールに成功すると php コマンドが利用できるようになります。

$ php -v
PHP 7.1.0 (cli) (built: Dec  2 2016 14:02:04) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies

では、PHP 7.1.0 の新機能を試してみます。

nullable な型

関数の型宣言(PHP5ではタイプヒンティングとも呼ばれていました)で null を許容する仕組みが追加されました。nullable な型を使うためには型名の前に ? を付けます。

<?php
declare(strict_types=1);    // 確認のため厳密な型チェックを有効にする

// $flgはbool型かnull
// 戻り値はstring型かnull
function foo(?bool $flg): ?string 
{
    if (is_null($flg)) {
        return null;
    }

    return $flg ? 'Yes' : 'No';
}

echo foo(true);    // 文字列 'Yes' を返す
echo foo(false);   // 文字列 'No' を返す
echo foo(null);    // nullを返す
echo foo();        // エラー(Fatal error: Uncaught ArgumentCountError)
echo foo(1);       // エラー(Fatal error: Uncaught TypeError)

void 関数

値を返さない関数の戻り値の型にvoidを指定できるようになりました。

<?php
function foo(): void 
{
    echo 'Hello, world.';
}

[ ]構文による配列の分割代入

配列の各要素を変数に代入する際に、[]を使ってlist()よりも簡単に書けるようになりました。

<?php
$array = [1, 2, 3];
list($a, $b, $c) = $array;  // PHP7.0ではlist()で分割代入できる
[$a, $b, $c] = $array;      // PHP7.1では[]構文で分割代入できる

クラス内定数がアクセス権をサポート

クラス内の定数にアクセス権を指定できるようになりました。

<?php
class Foo 
{
    const BAR1 = 1;    // 指定しない場合はpublic

    private const BAR2 = 2;
    protected const BAR3 = 3;
    public const BAR4 = 4;
}

echo Foo::BAR1;    // 1を表示
echo Foo::BAR2;    // エラー(Fatal error: Uncaught Error)
echo Foo::BAR3;    // エラー(Fatal error: Uncaught Error)
echo Foo::BAR4;    // 4を表示

iterable 擬似型

関数の型宣言で配列かTraversableインターフェイスを実装したオブジェクトを示すiterableを指定できるようになりました。

<?php
function foo(iterable $ite): void 
{
    foreach ($ite as $value) {
        echo $value;
    }
}

foo([1, 2, 3]);    // 123を表示
foo('Hello');      // エラー(Fatal error: Uncaught TypeError)

複数の例外を1つのcatch構文で捕捉

複数の異なる型の例外を、1つのcatch構文で捕捉できるようになりました。

<?php
try {
   
} catch (ExceptionType1 | ExceptionType2 $e) {
    // 2つの例外 ExceptionType1 と ExceptionType2 を捕捉します
} catch (\Exception $e) {
   
}

list() におけるキーのサポート

配列をlist()を使って分割代入する際に、キーで指定できるようになりました。

<?php
$array = ['db_name' => 'test', 'db_user' => 'root', 'db_password' => 'secret'];

// 順番を気にすることなく、キーに紐づく変数に代入できる
list(
    'db_user' => $user,
    'db_password' => $password,
    'db_name' => $database
) = $array;

前述の[]による分割代入を利用するとより簡潔に書くことができます。

<?php
$array = ['db_name' => 'test', 'db_user' => 'root', 'db_password' => 'secret'];

// list()の代わりに[]を利用して分割代入
[
    'db_user' => $user,
    'db_password' => $password,
    'db_name' => $database
] = $array;

文字列のオフセットに負数をサポート

文字列の各文字に[]{}を使ってアクセスする際に、負数を使えるようになりました。

<?php
$string = 'Hello, world.';
$string[-1] = '!';  // 後ろから1文字目を '!' に上書き
echo $string;       // 'Hello, world!' を表示

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)

docs.hatenablog.jp

Windows 10 の Bash on Ubuntu on Windows で Node.js/gulp/Sass を実行する

現在 Windows 10 Insider Preview で提供され、今夏に正式リリース予定の Bash on Ubuntu on Windows では Node.js を利用することができます。今回は Node.js をインストールし、さらに gulp と Sass を実行してみます。

なお、Bash on Ubuntu on Windows 自体のインストール方法は以下の記事を参照してください。今回利用したのは Windows 10 Insider Preview Build 14390 です。 docs.hatenablog.jp

Node.js

まず、Bash on Ubuntu on Windows を起動して次のコマンドを実行し、公式の Node.js の安定バージョンである4系をインストールします。

curl -sL https://deb.nodesource.com/setup_4.x | bash -
apt-get install -y nodejs

インストールが成功すると node コマンドが利用可能になります。次のコマンドで Node.js のバージョン番号を確認できます。

node -v

パッケージマネージャである npm コマンドも利用可能になります。次のコマンドで npm のバージョン番号を確認できます。

npm -v

Node.js は JavaScript の実行環境ですので、簡単な JavaScript のコードを実行して動作を確認してみます。以下のコードを hello.js というファイル名で保存します。

console.log('Hello, Node.');

コードが正しければ、次のコマンドを実行すると画面に「Hello, Node.」と出力されます。

node hello.js

gulp

次はタスクランナーである gulp をパッケージマネージャ npm でインストールします。次のコマンドを実行して、gulp のコマンドラインツールをインストールします。

npm install -g gulp-cli

インストールが成功すると gulp コマンドが利用可能になります。次のコマンドで gulp のバージョン番号を確認できます。

gulp -v

では、gulp で簡単なタスクを実行して動作を確認してみます。まず、適当なディレクトリで次のコマンドを実行します。今回は作業用にnodeという名前のディレクトリを作成しました。

npm init

いくつか質問されますが、今回はすべてデフォルト値のまま(すべてエンターキーを押して)、最後に Is this ok? (yes) と表示されるので yes と入力します。

さらに次のコマンドを実行します。

npm install --save-dev gulp

これで gulp を実行する環境ができました。以下のコードを gulpfile.js というファイル名で保存します。

var gulp = require('gulp');

gulp.task('default', function() {
    console.log('Hello, gulp.');
});

コードが正しければ、次のコマンドを実行すると画面に「Hello, gulp.」と出力されます。

gulp

Sass

最後は Sass をインストールします。次のコマンドを実行して、gulp のタスクとして実行できる gulp-sass をインストールします。

npm install --save-dev gulp-sass

では、簡単な Sass のコードを CSS に変換してみます。まず、Sass のファイルを保存するディレクトリと、変換後の CSS ファイルを保存するディレクトリを作成しておきます。今回は sass-src ディレクトリと sass-dest ディレクトリを作成しました。

mkdir sass-src sass-dest

次に、以下のコードを sample.scss というファイル名で sass-src ディレクトリに保存します。

$sample-color: #f00;
body {
  color: $sample-color;
}

次に、gulpfile.js ファイルを次のように書き換えます。

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function() {
    gulp.src('./sass-src/*.scss')
        .pipe(sass())
        .pipe(gulp.dest('./sass-dest'));
});

コードが正しければ、次のコマンドを実行すると sass-dest ディレクトリに sample.css というファイルが作成されます。

gulp sass

sample.css を見ると正しく CSS に変換されています。

body {
  color: #f00; }

このように、Bash on Ubuntu on Windows でも通常の Ubuntu にインストールするのとほぼ同じ操作で Node.js、gulp、Sass が利用できました。

Web制作者のためのSassの教科書 これからのWebデザインの現場で必須のCSSメタ言語

Web制作者のためのSassの教科書 これからのWebデザインの現場で必須のCSSメタ言語

Mozilla の新ブラウザエンジン Servo の Developer Preview を試してみる

Mozilla Research が開発する新しいブラウザエンジン Servo の Developer Preview がリリースされました。Servo はより良い並列性、モジュール性、セキュリティ、ハイパフォーマンスを目指して開発されており、次のような特徴があります。

現在は Mac OS XLinux 用のバイナリファイルが提供されているため、すぐに試すことができます。なお、今後は WindowsAndroid 用も提供される予定です。それでは Linux 用のバイナリファイルをダウンロードして起動してみます。OS は VirtualBox 上の Ubuntu Desktop 16.04 LTS を使用しました。

まず、公式サイトの Download Servo nightly build からダウンロードページへ移動し、Linux Build (64-bit) ボタンを押して最新のバイナリファイルをダウンロードします。

https://servo.org/

次のコマンドでダウンロードしたファイルを展開します。

tar zxf servo-latest.tar.gz

展開すると servo ディレクトリが作成されるので、その中のシェルスクリプト runservo.sh を実行します。

cd servo
./runservo.sh

起動が成功すると次のようなアプリケーションが起動します。デフォルトでいくつかのブックマークが表示されています。

f:id:hontonodeai:20160709143909p:plain

f:id:hontonodeai:20160709144331p:plain

今のところアドレスバーとタグの切り替え機能がある程度のシンプルなUIです。Alt + で前のページへ戻り、Alt + で次のページへ進みます。また、いくつか日本語ページを表示してみましたが、EUC-JPで書かれたHTMLを表示すると文字化けしてしまうようです。

将来的には、Gecko に Rust/Servo のコンポーネントが搭載される予定です。