Hatena::ブログ(Diary)

Scrapcode@はてなダイアリー このページをアンテナに追加 RSSフィード

2010-05-03

Kansai.pm第12回ミーティング

5月1日に奈良県・王寺やわらぎ会館で開催された「Kansai.pm第12回ミーティング」に参加してきました。

参加者・運営者の皆様方、ありがとうございました。

今回も準備・運営をほとんど任せてしまった…。もっと動かないと…。

ImageMagickとImage::ExifToolのキホン

初歩的な内容ですが、ImageMagickとImage::ExifToolについて少し発表させてもらいました。

発表資料 → http://www.scrapcode.net/files/ImageMagick-ImageExifTool.pdf

話したかったのは画像加工のテクニックではなく、画像加工後のExifの不整合の問題だったのでした。

ダイアリーで書こうと思って途中まで下書きしていたものを、構成をやり直して発表に使いました。

GeoHexを使ってみた

おまけネタとして用意していたものも、ネット接続を提供していただけたので発表させてもらいました。

これは別エントリーとして書きます。

KML Hex Map

GeoHex(ジオヘックス) | geogames.net」で公開されている「GeoHex」を利用させていただいて、次のようなものを作ってみました。

KML Hex Map - http://map.conoha.net/kmlhex/

これはなに?

Web上で公開されているKMLに記録されている位置を、Googleマップ上にGeoHexを用いて表示するだけのものです。

KMLはどこにあるの?

foursquareユーザーならここにあります。他に「ルートラボ - LatLongLab」や、はてなfotolife(位置情報を付けていれば)にもあります。

とりあえずこの3サイトのKMLなら利用できると思います。

使い方は?

KML Hex Map」にアクセスして、KMLURLを入力し、「Load」ボタンをクリックしてください。

表示速度の切り替えは、Load後に行ってください。

Hexの色が変わる場合と変わらない場合があるけど?

foursquareKMLの場合だけ、チェックインした日ごとに色が変わるようになっています。

色テーブルは後日変更するかも知れません。

iPhoneでも見られる?

iPhoneでも一応見られます。あまりポイントの多いKMLだと、非常に重くなってしまいますが。

それ以前に、iPhoneKMLURLを入力するのが面倒で、わざわざ見る気にはならないかも…。あくまで「一応」ということで。

どうして作ったの?

id:naskin氏が作った「404 Not Found」という、foursquareでチェックインした最(東|西|南|北)点を表示するサービスにインスパイアを受けて、ずっと使ってみたいと思っていたGeoHexを使ってみました。仕組みは簡単なので、Kansai.pm第12回ミーティングのおまけネタ程度に使えるかな、と*1

…というようなものです。

万人うけするものではないけど、こういうのが好きな人はきっと居る…はず…!

*1KMLの解析とHexCode生成に、サーバー側でPerlを使ってます

2010-03-19

CGI::Application::Plugin::Config::YAMLでハマるかもしれないこと

CGI::Application::Plugin::Config::YAML(以降、CAP::Config::YAMLと表記)で以前ハマったのにすっかり忘れていて、またハマったのでメモ。

複数ファイルを読み込んだ場合、引数無しのconfig_paramは期待する値を返さない

CAP::Config::YAMLは、以下のようにして複数のYAMLファイルを読み込むことができます。

# ここで $self は CGI::Applicationを継承して作ったアプリケーションクラスのオブジェクトのこと

# YAMLファイル設定
$self->config_file( 'config.yaml' );

# 追加読み込み
$self->config_read( 'aaa.yaml' );
$self->config_read( 'bbb.yaml' );

トップレベルのキーが重複する場合は、後勝ちで上書きになります。重複しない場合は単純に追加されます。

次に、config_paramメソッドで全てのデータハッシュを取得するために、引数無しで呼び出します。

my $hash = $self->config_param;

が、これではダメなのです。これで取得できるのは、config_fileメソッドで指定したファイルのデータのみなのです。

config_paramメソッドを引数無しで呼び出した時は内部でget_hashメソッドが呼び出されるのですが、このget_hashメソッドではconfig_fileメソッドで指定したYAMLファイルのみを再度読み込んで解析した結果を返しているのです。

sub get_hash {
    my $self = shift;
    my $yaml;

    open(FH,'<',$self->config_file) or die "Can't open $self->config_file; $!\n";
    while (my $line = <FH>) {
        next if ($line =~ /^\-{3,}/);
        next if ($line =~ /^#/);
        next if ($line =~ /^$/);
        $yaml .= $line;
    }
    close(FH);

    my $tmpyaml = YAML::Load($yaml);
    return $tmpyaml;
}

仕方が無いので、内部のConfig::YAMLオブジェクトを直接参照することにします。

my $hash = $self->config;
# この場合、ref $hash が Config::YAMLになってしまう

オブジェクトを直接参照するのが気持ち悪い場合は、オブジェクトハッシュを一旦デリファレンスしておきます。

my $hash = { %{ $self->config } };
# この場合、ref $hash は HASH になる

Config::YAMLが内部で使う値も含まれてしまいますが、YAMLファイル名とフラグなので気にしなくてもいいでしょう。

…気になる場合は、YAMLファイルのハッシュキーにアンダースコアから始まるものが無いという前提で、次のようにするとか。

my $hash = {
    map { ( $_ => $self->config_param( $_ ) ) }
    grep { not /^_/ }
    keys %{ $self->config }
};

config_paramで値の追加・変更を行ったら、その都度YAMLファイルを書き換えてしまう

config_paramメソッドで値の追加・変更を行った場合はconfig_fileメソッドで指定したYAMLファイルを都度上書きしてしまいます。

$self->config_file( 'config.yaml' );
$self->config_param( new_key => 'new_value' );

# config.yaml に
#   new_key: new_value
# が追加されたものが書き込まれる

複数ファイルの読み込みをした場合はYAMLファイルの内容が大きく変わってしまうかも知れないので、config_paramメソッドで値を追加・変更しない方がいいですね。

2010-03-16

YAML.pmのLoadFileとDumpFileでUTF-8しか使えなくなった

PurePerlなYAMLモジュールYAML.pmで、バージョン0.71からLoadFileとDumpFileはUTF-8しか使えなくなっていました。

LoadFileでは

binmode $IN, ':utf8';

DumpFileでは

binmode $OUT, ':utf8';

のようにPerlIOレイヤでutf8が指定されるようになったためです。

UTF-8を使えってことですかね。

なお、LoadとDumpはeuc-jpでも使えました。

2010-02-24

モバイル版はてなのログインページはSSLへのリンクがない

今のモバイルはてな携帯電話iPhoneAndroidDSi)のログインページに変わってから、SSLに切り替えるリンクがなくなりました。

f:id:khashi:20100224202842j:image:h300

はてなアイデアに2月1日にidea:26265として登録したのですが、未だに検討すらされていません。

iPod touchはてなログインするときはURL欄を編集してhttpsに変えてからログインしています。が、携帯電話ではURL書き換えは非常に面倒なので、自分でSSLログインページをブックマークでもしておかないといけません。

…と思って携帯(au W53CA)でhttps://www.hatena.ne.jp/mobile/loginにアクセスしてみたところ、

このサイトは安全でない可能性があるため接続できません(発行者エラー)

という、携帯電話が出すエラーが表示されてしまいました。

怖くて携帯からはてなにID、パスワードを使ってログインできない…!

かんたんログインログインしてますが、「高木浩光@自宅の日記 - はてなのかんたんログインがオッピロゲだった件」を見るとそれも心配だし…。

いやはや、恐ろしい。

2010-02-06

パスワードリマインダーの実装を考える

サイト運営者の視点で、パスワードリマインダーの実装について考えてみます。

(1) 登録メールアドレスに生パスワードを送信する

アチコチでよく見かけますが、パスワードの扱いが軽すぎます。

メールを盗聴されるとパスワードが漏れます。パスワードの使い回しが少なくないと思われる現在、該当サイトだけでなく他のサイトもアカウントを乗っ取られる危険性があります。

また、該当サイトではデータベースに生パスワード、もしくは復号可能なパスワードを保存している事になります。万が一該当サイトのサーバークラックされた場合、データベースのデータと復号方法まで一緒に漏れる可能性があります。

(2) 登録メールアドレスにランダムな仮パスワードを送信する

メールを盗聴されるとその仮パスワードを使ってログインされ、アカウントが乗っ取られます。パスワードを変更されてしまうとどうしようもなくなります。

盗聴者より先にログインしてパスワードを変更してしまえば、被害を回避できます。

パスワードが漏れても、アカウントを乗っ取られるのは該当サイトだけで済む分、(1)よりマシです。

(3) (2)に加え、登録情報との照合を行う

生年月日や秘密の質問など、ユーザー登録情報との照合を行うことにより、第三者による勝手な仮パスワード申請を避ける事ができます。

しかし、メールを盗聴されると危険なのは(2)と変わりません。

パスワード申請時ではなく、仮パスワードでのログイン時に照合を行うのであれば、安全性は高まります。

(4) 登録メールアドレスパスワード再設定用のURLを送信する

メールを盗聴されると危険なのは(1)と同じですが、盗聴者より先にパスワードを再設定してしまえば*1、被害を回避できます。

盗聴者が勝手にパスワード再設定用のURLを申請してしまうことができると、本人より先にパスワードを再設定されてしまう危険があります。

パスワードが見えてしまう事が無いので、もしメールを盗聴されて先にパスワード再設定を行われたとしても、アカウントを乗っ取られるのは該当サイトだけで済む分、(1)よりマシです。

(5) (4)に加え、登録情報との照合を行う

生年月日や秘密の質問など、ユーザー登録情報との照合を行うことにより、もしパスワード再設定用URLが漏れてもアカウントを乗っ取られる可能性がかなり低くなります。

ただし、パスワード再設定用URLをメール送信する前にこの照合を行った場合の危険性は(4)と同じになってしまいます。照合を行う場合は、パスワード再設定の段階で行うべきです。

(6) 登録メールアドレスパスワード再設定用URLを送信し、リマインダーフォームに確認コードを表示する。

  1. リマインダーのフォームで登録情報との照合を行う。
  2. 登録メールアドレスパスワード再設定用のランダムなURLを送信する。
  3. リマインダーの「メールを送信しました」表示と共に、ランダムな確認コードを表示する。
  4. ユーザーはパスワード再設定用URLにアクセスし、確認コードを入力し、パスワード再設定を行う。
  5. 使用済みURLと確認コードは破棄する。

メールを盗聴されても、パスワード再設定用URLだけではパスワードを変更できません。また、確認コードの表示がSSLで保護されていれば、確認コードを傍受されることもありません。

(7) 登録メールアドレスに確認コードを送信する

  1. リマインダーのフォームで登録情報との照合を行う。
  2. 登録メールアドレスにランダムな確認コードを送信する。
  3. セッションデータとしてサーバー側で確認コードを保持し、ユーザーからの確認コード入力を待つ。
  4. ユーザーがメールの確認コードを入力。
  5. パスワード再設定を行う。
  6. 使用済み確認コードは破棄する。

メールを盗聴されても確認コードのみなので、盗聴者がログインパスワード変更を行う事はできません。

セッションハイジャックとメールの盗聴が同時に発生しなければ、アカウントを乗っ取られる事は無いと思います。

この記事を書いたキッカケ

(6)と(7)はどこかで使われているかな?

(1)〜(5)に比べてメール盗聴に強く、実装も難しくないと思いますが、何か見落としている問題点があればコメントいただけるとうれしいです。

この記事を書いたキッカケは、去年見たユーザー登録型のサイトで(1)の事例が多くてウンザリしたからです。パスワードみたいな秘匿性の高い情報を平文でネットワークを流れるメールに書いてはいけないというのは、電子メールを使い始める最初に注意されることだと思うのですが…最近はそうでもないのでしょうか?

最近はPOP over SSL / SMTP over SSLに対応したプロバイダも増えてきてはいますが、これらが保護できるのはメールクライアントと各サーバーとの間だけです。サーバー - サーバー間をSSLで保護されるかどうかは保証されません。また、受信者側がPOP over SSLに対応していないかも知れないし、対応していてもメールクライアントSSLを使う設定にしていないかも知れません。

メール盗聴が実際にどれぐらい発生するかはわかりませんが、サイト運営側は盗聴されてもユーザーに被害が及ばない仕組みを用意するべきです。

(2010-02-09 追記) 「登録情報との照合」について

文中で「生年月日や秘密の質問など」と書きましたが、生年月日はWebで公開しているプロフィールに書いている人も多いため、照合に使うには危険です。

秘密の質問はサイト側が用意している質問選択肢が全然秘密になっていないことが多く、質問内容を自由に決められない場合には、やはり危険です。「ペットの名前」や「出生地」などは、ブログなどで公開していることも多いでしょう。

Webサービスによっては登録情報がメールアドレス、ユーザーID、パスワードぐらいしか無い場合もあるので、第三者にでも簡単に照合できてしまうかもしれません。

第三者でも照合できるような場合は勝手にリマインダーを使ってしまえるため、どの方法でもメール盗聴と照合突破を同一の攻撃者にやられると無力です。

第三者による照合一致の確率を極力抑える事ができた場合は、メール盗聴されただけではパスワードを変更できない方法が安全です。

危険度が変わらないならどの方法でもいいかも知れませんが…、それでも(1)だけは勘弁して欲しいところです(これだけは危険度が別格かと)。

高機能で使いやすいけどパスワードの扱いが杜撰なサービスよりは、多少使いにくくてもパスワードの扱いがしっかりしているサービスを使いたいものです。

*1:ただし、再設定が完了したURLを即時無効にすること