トップ 最新 追記   RSS 1.0 FEED  

Journal InTime


2017-12-15 (Fri) [長年日記]

_ ファイルオープンの罠

僕が書いたNet::FTPのコードに脆弱性報告があり、修正版がリリースされた。関係者のみなさん、ありがとうございました。

問題があったのは以下のようなコードだった。

def getbinaryfile(remotefile, localfile = File.basename(remotefile),
                  blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
  f = nil
  result = nil
  if localfile
    if @resume
      rest_offset = File.size?(localfile)
      f = open(localfile, "a")
    else
      rest_offset = nil
      f = open(localfile, "w")

ここでKernel#openを使っていたのが問題で、localfile|で始まる文字列だと外部コマンドが実行されてしまう。 しかも、まずいことにlocalfileのデフォルト値はFile.basename(remotefile)なので、悪意のあるFTP上に|で始まる名前のファイルがあって、ディレクトリ内のファイルをすべてダウンロードするようなプログラムを書いていると、クライアント側でコマンドが実行されてしまう。パイプ以外ではopen-uriをrequireしているようなケースでも何かまずいことができてしまうかもしれない。

普段書き捨てのコード以外ではFile.openの方を使うのだけど、確認したところ1997年8月13日リリースのruby-1.1a0のころからKernel#openを使っていたようだ。

ちなみにopen以外にも罠があって、例えば

p File.read("|echo hello") #=> "hello"

のようにしてもコマンドが実行されてしまう。

これは、Fileクラスには実はreadは定義されておらず、IO.readが呼び出されるため。 他には、binread, write, binwrite, foreach, readlinesなども同様の罠がある。 わざわざFile.と書いてパイプをオープンしている意図的なコードはそうそうないと思うので、Fileクラスにパイプをオープンしないバージョンを追加してオーバーライドした方がよいのではないかと思うが、今さら2.5には間に合わないだろう。

当面は引数をFile.expand_pathでフルパスに展開するとか、先にFile.statするなどすれば、上記のような罠を回避することができると思う。

Tags: Ruby

2017-12-20 (Wed) [長年日記]

_ PGP鍵の更新

PGP鍵の有効期限が切れたので新しい鍵を作成した。

pub   rsa4096/AD744A13 2017-12-20 [SC] [expires: 2027-12-19]
      Key fingerprint = 7645 6F57 D834 E17B ACEF  5239 568A D8CE AD74 4A13
uid         [ultimate] Shugo Maeda <shugo@ruby-lang.org>
uid         [ultimate] Shugo Maeda <shugo@netlab.jp>
uid         [ultimate] Shugo Maeda <shugo@debian.org>
sub   rsa4096/636AA7CD 2017-12-20 [E]

古い鍵で署名した上でpgp.mit.eduとpgp.nic.ad.jpに登録したので、古い鍵での署名が確認できる人は新しい鍵に署名していただけるとありがたい。


2017-12-21 (Thu) [長年日記]

_ PGP/MIME

MournmailにPGP/MIMEを実装した(表示は前から一部実装してあった)。

mail-gpgを使って

m = Mail.new
...
m.gpg(sign: true, encrypt: true)
m.deliver

とすると、PGP/MIMEで署名・暗号化されたメールが送信されるが、delivery_handlerとして実装されているのでdeliver!だと署名・暗号化されないので注意。*1

署名と暗号化の両方を行った場合は、multipart/encryptedの中にmultipart/signedを入れる形式*2ではなく、以下のようにOpenPGPで署名と暗号化を同時に行ったものをmultipart/encryptedにする形式*3になる。

Content-Type: multipart/encrypted;
 boundary="--==_mimepart_5a3b0cf4ac39a_8953ff49d912018280a";
 protocol="application/pgp-encrypted"
Content-Transfer-Encoding: 7bit

This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156)
----==_mimepart_5a3b0cf4ac39a_8953ff49d912018280a
Content-Type: application/pgp-encrypted
Content-Transfer-Encoding: 7bit
Content-Description: PGP/MIME Versions Identification

Version: 1
----==_mimepart_5a3b0cf4ac39a_8953ff49d912018280a
Content-Type: application/octet-stream;
 name=encrypted.asc
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename=encrypted.asc
Content-Description: OpenPGP encrypted message
Content-ID: <5a3b0cfbd80bc_8953ff49d9120182843b@lexington.mail>

-----BEGIN PGP MESSAGE-----
Version: GnuPG v2

hQIMA/zS+2ljaqfNARAA2Zh9f6f5Y55AfzRhCzMSe13R5EXBD6uI+R/VtQomhsag
...
-----END PGP MESSAGE-----

----==_mimepart_5a3b0cf4ac39a_8953ff49d912018280a--

Mewでは署名を検証できたけど、SEMIだと署名の検証方法がわからなかった(UI的に署名されているかどうかもわからないような)。

*1  interceptorにしようというissueがある。

*2  RFC 3156の6.1 RFC 1847 Encapsulationで規定されている形式。the data is first signed as a multipart/signature bodyと書いてあるのはmultipart/signedのtypoのような気がする。

*3  RFC 3156の6.2 Combined methodで規定されている形式。


2017-12-23 (Sat) [長年日記]

_ 走り納め

photo

少し暖かくなったので、バッテリーの充電のために近所を走ってきた。

峠道に融雪剤が撒いてあったので、帰ってからざっと洗車した。 多分しばらく乗らないのでバッテリーのマイナス端子を外しておいた。

次乗れるのはいつになるだろうか。

Tags: 250DUKE

2017-12-25 (Mon) [長年日記]

_ Ruby 2.5.0へのアップグレード

Ruby 2.5.0がリリースされたので、この日記をRuby 2.5.0にアップグレードした。

今のところtDiaryの動作はとくに問題なさそうだが、2.5.0のバグっぽい挙動を見つけてしまったような……。

Tags: Ruby

_ モジュールのrefineのバグ

モジュールをrefineした際のバグをいくつか直したつもりだったが、以下のケースでusing Dしていないのにrefineしただけで挙動が変わってしまうようだ。

module A
  def foo
    puts "A#foo"
    super
  end
end

class B
  def foo
    puts "B#foo"
  end
end

class C < B
  include A

  def foo
    puts "C#foo"
    super
  end
end

module D
  refine A do
    def foo
    end
  end
end

C.new.foo

using Dした時にsuperでBを辿れないのは仕方ないかなと思っていたのだが、using Dしてないのにこうなるのはちょっとまずい……。

とりあえず、Bug #14232として登録しておいた。

Tags: Ruby

2017-12-29 (Fri) [長年日記]

_ Debian stretchへの移行

photo

しばらくUbuntuを使っていたが、RubyコミッタでDebianをメインにしている人が少なくなっていそうなのでDebian strechに移行した。

VirtualBoxなので、クリーンインストールしたDebian上にUbuntuのディスクを追加して/home/shugoをbind mountしたので、セットアップは比較的楽にできた。 はじめてUbuntu使った時はセットアップが楽だと思ったけど、今だとDebianでもそんなに変わらないかも。

ちょっとはまったのは、

  • .ssh/configにIdentitiesOnly yesと書かないと、Ed25519鍵を使う時にid_ed25519-certが見つからなくて認証に失敗した。
  • gnome-keyring-daemonが自動起動するようになっていなかったので、Chromeの起動時に毎回パスワードを求められた。
  • 最近のGnomeはかっこいいけど重かった(XFCEに戻した)。

といったところか。

Tags: Debian