Home > Archives > 2011-04

2011-04

ウェブサービスの立ち上げとXSS対策

mesoがDBCLSに着任してまずやろうとしていることは、転写産物=RNAベースで、塩基配列、文献、プローブ、siRNA、等々を整理した統合データベースをつくることだ。従来のデータベースの多くは何でもゲノムにマッピングするという発想だったが、biologistはどちらかというと遺伝子や転写産物を単位にものごとを考えているはずなので、転写産物に知識をマッピングするほうが自然だろう。しかも、それをフリーワードや塩基配列からサクサク検索できるサイトをつくれば有用に違いない。

プロトタイプができたらここで紹介する予定だが、今日はグループのメンバーに作成途中のwebを回覧したところ、即座にXSSを仕掛けられて脆弱性が露見するという情けないことがおきたので対策を施すことにした。

XSSとは

XSS(クロスサイトスクリプティング)とは何か。例を挙げると、ウェブの入力フォームに、お名前:「<script>alert(“うへへ”)</script>」のようないじわるな文字列を入力すると、返ってきたHTMLに含まれる「ようこそ、○○さん」のところが「ようこそ、<script>alert(“うへへ”)</script> さん」になりJavaScriptとして解釈されてしまう、こういった脆弱性を突く行為だ。悪用されれば深刻な被害が出かねないので対策が必須である。詳しくは、今回参考にした「@IT: クロスサイトスクリプティング対策の基本」などを参照してほしい。

mesoの作成しているページには早速 @iNut たんがあやしいクエリをsubmitしたところ、下記のようにJavaScriptのalert()が実行されて奇妙なポップアップが表示された。

駄目だこれは(=_=。ちなみに@iNut様のブログ、Chateau Togo によると、うちのグループのスタンダードは、

僕がこの牧場で教わったことは3つありますー
一つ、書いたコードは恥を承知で晒せ。
一つ、コマンドの使い方が分からなければmanを読め。
一つ、フォームを見たらとりあえずXSSを打ち込め。

ということらしい。meso涙目。

XSS対策

XSS対策をする場所は基本的に2箇所。入力データのチェックと、HTML出力前のチェックだ。下記の特殊文字をHTMLの実態参照に置き換えるか、消去してしまえば、タグとして解釈されなくてすむ。これをサニタイズ(無害化)する、と言うらしい。

HTMLのタグとして解釈される可能性がある文字:

  • 「<」→ &lt;
  • 「>」→ &gt;
  • 「&」→ &amp;

タグ中で<a href=”hoge”>のような属性値の開始・終了に使われる文字:

  • 「’」→ &#39;
  • 「”」→ &quot;

ただ、上記のような置き換えを考える前に、本当にそんな文字を受け付ける必要があるのか? を検討するべきだろう。たとえば郵便番号は半角数字3桁+4桁と決まっているので、それ以外の文字列は入力の時点でチェックしてはねるのが先決だ。入力のチェックを厳しくすることは、XSS以外の脆弱性(オーバーフロー等)の対策にもなる。

なお、ここに書いたことはあくまで基本なのでこれだけでは対策として不十分だが、何もしないのと比べると大幅にリスクを減らすことができるだろう。詳しくは「XSS 対策」でググってさらに調べるべし。

実験用のコードとサービス用のコードは違う

とりあえず上記+αの対策で@iNutさんの意地悪クエリには対処できた。しかしこんどは @chalkless さんから、あるクエリを投げるとDBのほぼ全件が返ってくるとか、長いクエリを投げるとオーバーフローするといった指摘をいただいた。meso涙がとまらない。

あたりまえのことだが、実験のために書くコードと、サービス提供のためのコードは違うのである。すべての条件分岐と、すべてのパラメータをチェックし、どんな入力を与えても(あるいは与えなくても)エラーで落ちないように書かなければいけない。たとえばperlのサブルーチンなどでよく出てくる、

my $query = $_[0] ;

というところは、

my $query = $_[0] || ‘デフォルト値’ ;

# 注)$_[0]がundef, 空白, ゼロだと「偽」が返るので || (or) の右項が評価され、
# $queryに ‘デフォルト値’ が入る。

などと書いておかないとundefとか空白だった場合にしぼうするだろうし、状況によって成功しないかもしれない文を実行するときには、

eval(実行したい文) or print_error(‘○○できませぬ!’) ;

# 注)evalの中身の文がコケてもプログラム自体は止まらずevalがゼロを返す。

のように「保険をかける」書き方が必要になってくる。また直接的な対策ではないが、デバッグしやすいコードを書く(例えばサブルーチン化を徹底する等)ことも、セキュリティ対策に寄与するだろう。(このへんの考え方は、メガバンクの勘定系システムをやっていたココ殿から昔レクチュアしていただいたことがある。銀行システムは超ガチガチで大変だったらしいけど・・・)

セキュリティ対策がある程度できたら、作成中のサイトをこの場で紹介したい。

Mac OS Xのコマンドラインでファイルを完璧にコピーする方法

Mac OS XのファイルはリソースフォークとかExtended Attribute、ACLといった情報を含んでおり、単なるcpとかscpではこのような情報が完璧に保持されるわけではない。

以前にMac OS X 10.5(Leopard)のコマンドラインで「完璧な」ファイルのコピーをおこなう方法を検討したのでその方法を書き留めておく。なお、Mac OS X 10.6(Snow Leopard)に移行してもそのまま利用可能だ。

基本的にはrsyncを使っている。rsyncのメリットは何と言っても差分コピーができること。たとえばホームディレクトリの定期的なバックアップに利用すれば、変更したファイルだけをコピーしてくれるので無駄がない。ファイルに変更がなくても、たとえばパーミッション等を変えるとちゃんとその情報がコピーされるのも隙がない。

もうひとつのメリットは、sshを利用して別のマシンに「完璧な」コピーを送れること。複数のMacをまったく同じ環境にセットアップしたり、リモートからバックアップを取るのに役立つ。ちなみにmesoは職場と自宅のMacを毎日この方法で同期していた。差分だけを転送するので数分程度で完了する(ただし巨大なファイルを転送するときは別)。

ここで注意が必要なのは、Leopardに標準で入っているrsyncは、どういうわけか毎回全てのファイルのリソースフォークをコピーして効率が悪いうえ、ハードリンクなどが保持されない。そこでrsyncにいくつかのパッチをあてソースからコンパイルすることにした。

参考

rsyncのコンパイル

curl -sO http://rsync.samba.org/ftp/rsync/src/rsync-3.0.4.tar.gz
curl -sO http://rsync.samba.org/ftp/rsync/src/rsync-patches-3.0.4.tar.gz

tar xzf rsync-3.0.4.tar.gz
tar xzf rsync-patches-3.0.4.tar.gz

cd rsync-3.0.4

# Apply patches relevant to preserving Mac OS X metadata

patch -p1 < patches/fileflags.diff
patch -p1 < patches/crtimes.diff

./configure
make

成功すればrsyncというバイナリができているはずだ。なお、ACLは10.4(Tiger)以降なので、Mac OS 10.3(Panther)上ではACL関係でエラーが出てコンパイルできない。

mesoは職場でIntel Mac、自宅でPowerPC Macを使っているので、両方の環境で実行できるようにユニバーサルバイナリ化した。

# Intel Macでmakeしたもの → rsync-3.0.4-i386/rsync
# PowerPC Macでmakeしたもの → rsync-3.0.4-PPC/rsync
# として、lipoでユニバーサルバイナリ化する。

lipo -create rsync-3.0.4-i386/rsync rsync-3.0.4-ppc/rsync -output rsync

# OS標準のrsyncと容易に区別できるよう、名前を変えておく。

cp -pi rsync ~/bin/rsync-304

Backup Bouncerによる評価

上記でmakeしたrsyncで「完璧な」コピーができるのかを、Backup Bouncerで検証。Backup Bouncerは、Mac OS Xのファイルが保持している各種情報が、コピー後にもちゃんと継承されているかどうかをテストするためのツール。ここで評価したのは、

  • Mac OS X 10.5 (Leopard)標準のrsync
  • rsyncx
  • rsync_hfs
  • 今回makeしたrsync-304

結果のみ示す。すべてのテスト項目をパスしたら、とりあえず完璧と呼ぶことにする。

テスト項目Leopard
rsync
rsyncxrsync_hfsrsync-304←304で使用
するオプション
basic-permissions (Critical)okokokok-a
timestamps (Critical)okokokok-a
symlinks (Critical)okokokok-a
symlink-ownershipokFAILFAILok-a
hardlinks (Important)FAILFAILFAILok-aH
resource-forks, on files (Critical)okokokok-aX
resource-forks,
on hardlinked files (Important)
FAILFAILFAILok-aHX
finder-flags (Critical)okFAILFAILok-aX
finder-locksFAILokFAILok–fileflags
creation-dateFAILokFAILok-aN
bsd-flagsokokokok-a
extended-attrs, on files (Important)okFAILFAILok-aX
extended-attrs, on directories (Important)okFAILFAILok-aX
extended-attrs, on symlinksFAILFAILFAILok-aX
access-control-lists, on files (Important)okFAILFAILok-aA
access-control-lists, on dirs (Important)okFAILFAILok-aA
fifookokokok-a
devicesokFAILokok-a
combo-tests, xattrs + rsrc forksokFAILFAILok-aX
combo-tests, lots of metadataokFAILFAILok-aAX

rsync-304のつかいかた

今回makeしたrsync-304ですべてのテストをパスすることがわかったので、これを使っていくことにした。与えるオプションは次の通り。

rsync-304 -avNHAX --fileflags --force-change --delete --stats

別のマシンにコピーするときは、そのマシンにも今回makeしたrsync-304を入れておく必要がある。そして、相手側のrsyncの位置をオプションで与える。たとえば、

--rsync-path=/Users/meso/bin/rsync-304

以上をまとめて、mesoは下記のようにscpxというエイリアスを設定し、コピーはすべてこれに任せている。

alias scpx='/Users/meso/bin/rsync-304 \
--rsync-path=/Users/meso/bin/rsync-304 \
-avNHAX --fileflags --force-change --delete --stats'

つかいかた:

# デスクトップにコピー

scpx hogehoge ~/Desktop/

# 別のマシンのデスクトップにコピー

scpx hogehoge meso@133.11.XX.XX:Desktop/

#  別のマシンにあるディレクトリをlocalにコピー

scpx meso@133.11.x.x:Desktop/hogehoge ./

# sshのポートを変更

scpx -e "ssh -p 12345" hogehoge meso@133.11.x.x:Desktop/

# ふつうにscpすると古いファイルは上書きされたり消されたり
# するが、obsolete以下に移動して取っておくにはこうする。
# 差分バックアップで過去のファイルを残したいときに便利。

scpx --backup --backup-dir=obsolete  meso  backup/

WordPressのインストールとblog開設

@meso_cacase は4/1付でライフサイエンス統合データベースセンター(DBCLS)に着任しました。wetな実験からは離れますが、データベースやソフトウェア開発の面から生命科学に大きく貢献できるような仕事をしていきたいと思っています。引き続きよろしくお願いいたします。

さて、まずは @twittoru さんの記事「麻婆豆腐新劇場版 YOU ARE (NOT) ANNINDOFU.」を参考にg86にwordpressをインストールしてみる。余談だが、こういうときに「書き留め、共有する」が積極的に実践されている環境は素晴らしいと思う。

curl -sO http://ja.wordpress.org/latest-ja.tar.gz

展開して ~/Sites/meme/ に設置。各ファイルのパーミションに注意。mesoはデフォルトで umask 077 しているのでこのまま解凍するとウェブ経由で読めない。umask 000 した後に tar xzf すればOK。続いて、@iNut さんにmysqlのユーザを作ってもらう。

% /opt/local/bin/mysql5 -umeso -p
Enter password: (パスワードを入力)
mysql> CREATE DATABASE meso_wp ;
mysql> quit ;

meme/ 内の wp-config-sample.php を wp-config.php にコピーして下記のように変更。

// ** MySQL 設定 – こちらの情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define(‘DB_NAME’, ‘meso_wp’);

/** MySQL データベースのユーザー名 */
define(‘DB_USER’, ‘meso’);

/** MySQL データベースのパスワード */
define(‘DB_PASSWORD’, ‘パスワードを記載’);

/** MySQL のホスト名 */
define(‘DB_HOST’, ‘localhost’);

あとはブラウザで / にアクセス。ガイダンスにしたがい若干の設定をすると完了。外観を簡単に変更できるらしい。「wordpress テーマ」でググるといろいろ出てくるが、ナイスなテーマを探していると1日つぶれてしまうので要注意。今回は wp.Vicuna というテーマを使ってみることにする。

さて、準備が整った。いままでDokuWikiを使ったことがあるので何となく勝手はわかる。今後はここを「実験ノート」として使い、「書き留め、共有する」ことを実践していこう。

(追記)

http://g86.dbcls.jp/~meso/ をwordpressのページ / にリダイレクトしてみる。.htaccessに

Redirect permanent /~meso/index.html /~meso/meme/

と書けばよいらしい。

Home > Archives > 2011-04

Search
Feeds
Meta

Return to page top