「顔面蒼白」などと使う「蒼」の字を使って「蒼い歌姫」なんて書いてたけども,「蒼」=「くすんだ,弱弱しい青」は歌姫にはふさわしくない色.「緑と青の中間」の「碧い歌姫」の方が正解です.要するにミクさんの事なんですけども.いやいやこの雑記のサブタイに意味なんて無いんですけども.
……というか,Google さんがなかなかクロールしに来てくれません.どうしたのかなと思いつつ,無理やり更新してみるテストでもあります.
そろそろこの場でこのように手動で記事を書くのはやめにして,自前の weblog を動かしたいのですが,その技術調査の途中でいろいろ勉強したので,もうちょっとだけ.
なんかそんな感じのスクリプトです.この場での詳しい解説は敢えてナシ!
BrandNew度:62%
現在,Java 6 Update 20 にアップデートせよとアナウンスが出ています.Java Development Toolkit にまつわる脆弱性で,攻撃者は何ら複雑奇怪なクラック作業など必要なく,本当に簡単に,任意の Java アプリケーションを実行できてしまいます.
そしてこれは「Java アプレット」とは全く別のお話.ブラウザで「アプレットを無効にする」設定をしておいたって無駄です.最近の Java をインストールしており,プラグインについて大して注意を払っていないユーザであれば,誰でもこの脆弱性を抱えています.
話は若干変わって.
先日,Google の日本語入力を試そうと思ったです.普段どおり,そのアプリケーションのインストーラか何かをダウンロードし,Windows のエクスプローラ上で setup.exe をダブルクリックしようと思っていました.Google Chrome もそうやってインストールしました.普通にあること.
Google のページを辿った瞬間でした.
驚いた事に,突然,何かのアプリケーションが起動したのです,
ビビりました.ページを開いただけなのに.まだ setup.exe もダウンロードすらしていなかったのに.何らかのプログラムが実行されるなんて思っちゃいませんでした.ワクチンソフトも反応しないし,すわ,未知の脆弱性かと.ついに私も踏んでしまったかと.
──結局,それはただの Google 日本語入力のインストーラでしたけども.
Java も Google も,そんな感じで「ブラウザでページを見てると,任意のプログラムを実行」する仕組みを我々のブラウザに組み入れているわけです──プラグインという形で.
Seamonkey 2.0.4 の Add-on Manager はこんな表示になっています.

赤いマークが付けられているのが,脆弱性がアナウンスされた Java Development Toolkit.こいつは要アップデートですが,そもそも何に役立つのか分からないので,無効にしておこうと思います.Seamonkey はこれらを個別に無効にする事ができます.
上の方には「Google Update」というプラグインもあります.これが,ページ上のリンクを踏んだだけで Google 日本語入力のインストーラが起動した件の正体.おそらく Google Chrome と一緒にインストールされたのでしょう.どうやら "application/x-vnd.google.oneclickctrl.8" という Mime-Type に反応して,このプラグインが起動するようです.
常識的に考えれば,このプラグインは,実行しようとするプログラムが Google 謹製のプログラムである事を (デジタル書名などで?) 確認してから実行する仕組みを備えているでしょう (ソースコードが公開されているらしいので,読めばいい話でもありますが).しかし,いつそのプロテクトが破られるとも限りません.そう頻繁に使うものでもないし,無効にしておきましょ.
Firefox でももちろん同様にプラグインの整理が可能.
Opera と Google Chrome では,プラグインの有効無効を個別に設定する項目は見当たりませんでした.個別に対応できるようになればいいのに.
しっかし,こんな感じでこっそりインストールされているプラグインてのは,あまり嬉しくないですよねえ.それとも Java や Google Chrome をインストールする時に,何か選択肢でも出てたのかな? 気づかなかったけど.
要注意度:85%
設定項目を見つけました.魅惑のコマンド「about:plugins」でしたとさ.
「about:うんたら」は Mozilla の系譜の専売特許かと思っていたら,わりといろんなブラウザでサポートされていたんすね.でも kitchen sink は Mozilla だけ!
って Sir Tim Berners-Lee が言い出しました.確かに,これが便利となる場面はそう多くはありません.
一体,どういう時に便利なんだろう?
TCP/IP 上でハイパーテキストを転送する主なプロトコルは 2 種類.HTTP と HTTPS です.HTTP なページから HTTPS なページに移る時は,まあ特にセキュリティ的な問題を考察する必要は無いと思います.しかし HTTPS なページから HTTP なページに移る際には,ブラウザは「ここから先の通信は暗号化されてないよ!」と警告を出すべきです.
「警告なんてうざい! HTTP から移れば HTTP のまま,HTTPS から移れば HTTPS のまま通信をしてもらうべきだよ! 何に気をつけてサイトを作ればいいの?」
ちょっと規模の大きいショッピングサイトなどでは,まれにそのような悩みが出るようです.特に,ドメインをまたがってページ遷移をするほどの大規模なサイトではね.
そんな時は,これ:
ようこそ one.example.com のショッピングサイトへ!
我々のもう一つのサイト,
<a href="//another.example.com/">another.example.com</a>
もどうぞ!
href 要素で URI を指定する時に,スキーム名 "http:" を省き,スラッシュ 2 つとドメイン名から書き出す事で,それまで HTTP 通信をしていたお客さんはそのまま HTTP 通信,それまで HTTPS 通信をしていたお客さんもそのまま HTTPS 通信でページを遷移する事ができます.このルールは,URI の厳密な文法を提案する RFC 3986 の 5.4 "Reference Resolution Examples" に詳しく書かれています (もちろん,この RFC は Sir Tim Berners-Lee らによるものです).
もしもスラッシュ 2 つが無ければ?
ここは one.example.com のショッピングサイトなんだけど
HTTP や HTTPS 通信のままでドメインを移るには
<a href="another.example.com/">これじゃだめだよね</a>
<a href=":another.example.com/">実はこれもだめ</a>
<a href=":/another.example.com/">同じくこれもだめ</a>
私が慣れ親しんでいる Windows のファイルシステムでは ":"(コロン) はファイル名として使えないので,その常識からすれば,後者のコロンで始まる href 要素は「ああ,スキームが省略されたんだね」と分かります.しかし他の OS が採用するファイルシステムでは,コロンもファイル名として使えるものがあります.このページを置いてある New Coara さんのサーバも,ファイル名にコロンを使う事ができます.そういう事もあってか,前述の RFC 3986 でも,パスにコロンを使う事は禁止されていません.
つまり上記の例では,最初の例はもちろん,2 番目と 3 番目も「現在のディレクトリからの相対パス」と見なさざるを得ないのです.
……と熱く語ってみても,2 つのスラッシュが便利なのは,こういう限られた状況以外には無さそうなんですけどね.
熱血度:85%
それでも,二つのスラッシュが不恰好であるのは,やはり同感ではあります.
のような仕様にすれば,二つのスラッシュは不要となるわけですね.まあでも今さら.
「どんな時に URL からプロトコルを省略したいか」の点,もっと身近で,結構多用されている例がありました.
21 世紀に入って少し経ったくらいから,(いろんな人がいろんな発明をしましたが) 主に Google のおかげで JavaScript の威力が再評価されるようになりました.それと大体同時期に "WebAPI" という考え方も生まれ,JavaScript と組み合わせて WWW の可能性を拡げました.
よくあるのは,こんなの.
<script type="text/javascript" src="//webapi.example.net/webapi.js"></script>
こうする事で,http なページから参照する時も,https なページから参照する時も,プロトコルを換えずに読ませる事が出来るわけですね.
ただし,これを代替する方法も結構使われているようで,例えば google-analytics ではこんな感じのスクリプトで WebAPI を参照するようになっています.
<script text="text/javascript">
var host = (document.location.protocol == "https:") ? "https://ssl." : "http://www.";
var url = host + 'example.com/webapi.js';
document.write(unescape('%3cscript src="' + url + '">%3c/script>'));
</script>
変数 host を導出している行に注目.document.location.protocol を参照して,http か https かを調べているのですね.
「なぜ弱いのか」という本質については,「そういうアルゴリズムだから」以外の専門的なことは分かりませんけども.とりあえず,どれだけ弱いのかを実感する事が出来たのでメモ.
Windows 2000, Perl 5.8.8 (ActiveState のやつ) で次のバッチファイルを動かしました.バッチファイルとはいえ,結局 perl.exe で自分自身を動かすわけですけども.
@echo off
#
# 弱いと言われている乱数生成器が,実際にどれだけ弱いのかを
# 知るためのバッチファイル + perl コード
#
for /l %%c in (1, 1, 50) do (
perl -x %0
)
goto :EOF
-----------------------------------------------------------
ここから perl コードです
#!perl
print random_phrase(). "\n";
exit;
sub random_phrase
{
# 12文字のランダムな文字列を作るよ
my $len = 12;
# 使用する文字は,この中からランダムで選ぶ
my @chars = ('a'..'z', 'A'..'Z', '0'..'9');
my $result = '';
# srand(time);
# 乱数のシードは明示的には設定しないものとする.
# この場合,perldocによると,5.004 よりも古いバージョンでは
# 自動的に srand(time) が行われていた,との事.
# 5.004 以降は,もっとよいシードが設定されているのかな?
# でも少しくらいプロセス番号でひっかきまわした方がいいかも
for (my $i = 0; $i <= ($$ % 17); $i++) {
rand();
}
while (length($result) < $len) {
my $rand = int(rand(0x100_0000)); # 0 〜 0xff_ffff の乱数
# なんか微妙にヘンな事をやって result を生成しているけども
# とにかくランダムであれば何だっていいと思ったから...
while (0 < $rand) {
$result .= $chars[$rand % @chars];
$rand >>= 8;
}
}
return substr($result, 0, $len);
}
以下のリストは,上記スクリプトで得られた文字列 50 個のうち,ある条件で 26 個抽出したもの.生成された 50 個の完全なリストは ./SPECIAL/20091011/randoms.htm を参照してください.
skNAQuusGgyf 82jwAUeqUAQA usyqcQQSQ0wB kOzU8baaMwAQ cijskGYo14Mh YoCmWwgyrmWY mWkKuowAXgy5 E6eAQqyIjOKI AQNOK20w9WgV AQJo420weYoy eqIgynmWVMC3 wAlciFskho4o wAZQShskccim skCE6UU87CYb gytmWIIm5MCp usWqcmciici8 YoUus9iGCciV iGesk34MfgyD wAIgyzyIsciu OKyaangy0S0R mWXAQfAQSU89 skoOKfgyoMCY gy8OKfkOwE65 QSjgyICYaCY5 GeRS0TKuAskG S0gaamYonusL
最初に得られた文字列は skNAQuusGgyf でした.さてこの先頭の 2 文字 "sk" が並ぶ確率は,62分の1 × 62分の1 = 3844分の1 です.じゃあ実際に "sk" がどれだけ含まれているのかを見てみると…… (注意:視覚的ブラウザでないと色が見えません.CSS2 にちゃんと対応したブラウザを推奨)
skNAQuusGgyf 82jwAUeqUAQA usyqcQQSQ0wB kOzU8baaMwAQ cijskGYo14Mh YoCmWwgyrmWY mWkKuowAXgy5 E6eAQqyIjOKI AQNOK20w9WgV AQJo420weYoy eqIgynmWVMC3 wAlciFskho4o wAZQShskccim skCE6UU87CYb gytmWIIm5MCp usWqcmciici8 YoUus9iGCciV iGesk34MfgyD wAIgyzyIsciu OKyaangy0S0R mWXAQfAQSU89 skoOKfgyoMCY gy8OKfkOwE65 QSjgyICYaCY5 GeRS0TKuAskG S0gaamYonusL
およ!? なんかヤバいくらい多くないすか.じゃあ "kN" は? "NA" は? ……そうして調べていくと……
skNAQuusGgyf 82jwAUeqUAQA AQ が含まれていた usyqcQQSQ0wB us 〃 kOzU8baaMwAQ AQ cijskGYo14Mh sk YoCmWwgyrmWY gy mWkKuowAXgy5 gy E6eAQqyIjOKI AQ AQNOK20w9WgV AQ AQJo420weYoy AQ eqIgynmWVMC3 gy wAlciFskho4o sk wAZQShskccim sk skCE6UU87CYb sk gytmWIIm5MCp gy usWqcmciici8 us YoUus9iGCciV us iGesk34MfgyD sk gy wAIgyzyIsciu gy OKyaangy0S0R gy mWXAQfAQSU89 AQ skoOKfgyoMCY sk gy gy8OKfkOwE65 gy QSjgyICYaCY5 gy GeRS0TKuAskG sk S0gaamYonusL us
惨憺たる結果に.
文字列生成のアルゴリズムを再度確認してみると,これら文字列は,rand() で得られた数値の 0〜7 ビット目を 0 文字目,8〜16 ビット目を 1 文字目……などとして取得します.つまり,rand() で得られた数値 0〜7 ビット目,8〜16 ビット目には,何かしらの,非常に簡単な相関が見えそうです.
ちゃんと調査するならば,いろいろ確率を求めてさあナントカ検定だ帰無仮説だあーだこーだですけども,残念ながら私にちゃんとした知識が無いので省略.でも「誕生日のパラドックス」を考慮するまでもなく,直感的に,こりゃまずい事が分かります.
これをパスワード (や,Web アプリのセッションID) に使っちゃうとしましょう.攻撃者は「このシステムのパスワードに使われる文字のうち,どの 2 文字も必ず "sk" とか "AQ" とか……うん,たった 1000 種類くらいに絞れるんだぜ」のように,意外にコンパクトな攻撃用辞書を作る事が出来てしまうかもしれません.
もっとじっくり観察すれば,さらに他の特徴を見抜くでしょう.例えば "sk" も "AQ" もどれもこれも,0 文字目から始まっているか,あるいは 3 文字目からか,あるいは 6 文字目からか,つまり 3 の倍数が関係している事が多いという規則があります (もっとも,その問題の本質は rand() ではなく私のアルゴリズムにありますが),仮に文字列生成アルゴリズムを公開しなかったとしても,そのアルゴリズムがなんとなく推測できてしまう気がしませんか?
例えば今回のようにランダムな文字列を作りたいのであれば,良質なライブラリが揃っています.
しかし,現実として,それらが使えない場合も多々あります.
(ランダム文字列とは関係ない話だけど) 最近,シビアな動作速度を求められる仕事の中で「HTTP レスポンスとして JSON で結果を返す」というものがありました.任意のオブジェクトから JSON 文字列を返すライブラリはいくつかありましたが,しかしどのライブラリも最低限の速度を達成できず,結局,自前での処理に落ち着いてしまいました.自分のプロジェクト内のオブジェクトなら,構造が自明なのでリフレクション等を使う必要が無く,速度が稼げたというわけです.
お世話になっているプロバイダ "New Coara" さんの共用 CGI サーバの環境は……詳しく書くのはあれですけども,必ずしも最新のイロイロが入っているとは限りません.例えば Digest や CGI::Session といったモダンなパッケージは入っていません.すでに我々ユーザが自前の CGI を動かしているのに,パッケージをアップデートしちゃって「なんか動かなくなったよ」となれば,coara さんには余計な仕事が増えてしまいます.我々ユーザに対するサポートは大切ですけども,そこは費用対効果.
あまり質の良くない rand() も,下位 16 ビット程度を切り捨てれば何とかなる,という話を聞きますね.
メルセンヌ・ツイスタ以外で,実装も簡単で評価されている擬似乱数といえば XorShift.しかしシードをどのような形で与えればいいのか,よく分からない人多数……私もその一人…….
他には,Web アプリのセッション ID を生成するならば,一方向ハッシュ関数を通すのが手軽で良さそう.大抵のセッションライブラリは,やはりハッシュ関数を用いているようです.
で,1 年と 9 ヶ月くらい前に作ったまま,使い道が無くて放置していた Perl のコードを公開するわけです.
処理速度などの特徴は特にないわけですけども,どうしてもこんな軽量ライブラリが必要な時ってありますよね.
ええ,さわってますとも.PowerShell とか初めて知りました.そんな感じで知った知識を,エライヒトに怒られない程度にメモ.よく分からない事が多すぎるので,以下の情報は間違いを多く含む可能性があります.
なんか素人丸出しですな (;´Д`) こんなんですいません