Forum: Ruby-dev [ruby-trunk - Bug #8995][Open] バイナリデータを文字列として encode! すると readbyte の結果が変化する

Eabad423977cfc6873b8f5df62b848a6?d=identicon&s=25 hsbt (Hiroshi SHIBATA) (Guest)
on 2013-10-08 09:50
(Received via mailing list)
Issue #8995 has been reported by hsbt (Hiroshi SHIBATA).

----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995

Author: hsbt (Hiroshi SHIBATA)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

https://github.com/rails/rails/blob/3-2-stable/act...

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (nobu)
on 2013-10-08 10:12
(Received via mailing list)
Issue #8995 has been updated by nobu (Nobuyoshi Nakada).


最小コードはこんな感じですね。
  $ ruby -E:UTF-8 -e 'p "\xff".encode.unpack("C*")'
  [239, 191, 189]
Encoding.default_internalをセットしていると、同じエンコーディング同士でも変換が起きているようです。
----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995#change-42331

Author: hsbt (Hiroshi SHIBATA)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

https://github.com/rails/rails/blob/3-2-stable/act...

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
Eabad423977cfc6873b8f5df62b848a6?d=identicon&s=25 hsbt (Hiroshi SHIBATA) (Guest)
on 2013-10-08 12:02
(Received via mailing list)
Issue #8995 has been updated by hsbt (Hiroshi SHIBATA).

Category set to core
Target version set to current: 2.1.0


----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995#change-42332

Author: hsbt (Hiroshi SHIBATA)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

https://github.com/rails/rails/blob/3-2-stable/act...

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (nobu)
on 2013-10-08 15:19
(Received via mailing list)
Issue #8995 has been updated by nobu (Nobuyoshi Nakada).

Description updated

理由はr40390です。

    * transcode.c (str_transcode0): If invalid: :replace is specified
for
      String#encode, replace invalid byte sequence even if the
destination
      encoding equals to the source encoding.

encode_paramsの引数はHTTPで渡ってくるパラメータのようですから、バイナリデータかどうかを判断する手がかりが他にあればともかく、valid_encodingでなければASCII-8BITにするくらいしかできないんじゃないでしょうか。
----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995#change-42335

Author: hsbt (Hiroshi SHIBATA)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

((<encode_params|URL:https://github.com/rails/rails/blob/3-2-stable/act...))

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (nobu)
on 2013-10-08 16:07
(Received via mailing list)
Issue #8995 has been updated by nobu (Nobuyoshi Nakada).

Status changed from Open to Third Party's Issue

まぁ、そもそもバイナリデータをエンコーディング変換したら壊れるのが当然ですね。
----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995#change-42336

Author: hsbt (Hiroshi SHIBATA)
Status: Third Party's Issue
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

((<encode_params|URL:https://github.com/rails/rails/blob/3-2-stable/act...))

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
Eabad423977cfc6873b8f5df62b848a6?d=identicon&s=25 hsbt (Hiroshi SHIBATA) (Guest)
on 2013-10-08 16:15
(Received via mailing list)
Issue #8995 has been updated by hsbt (Hiroshi SHIBATA).


rails の該当箇所は rails 3 リリース時から存在するもので、invalid な utf-8
をパラメータとして渡して攻撃するものを防御するためのコードのようです。いったん、rails 側で何とかできないか考えてきます。
----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995#change-42337

Author: hsbt (Hiroshi SHIBATA)
Status: Third Party's Issue
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

((<encode_params|URL:https://github.com/rails/rails/blob/3-2-stable/act...))

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (nobu)
on 2013-10-08 16:34
(Received via mailing list)
Issue #8995 has been updated by nobu (Nobuyoshi Nakada).


同じエンコーディング間では何もしていなかったので、防御にはなっていなかったんじゃないでしょうか。
----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995#change-42338

Author: hsbt (Hiroshi SHIBATA)
Status: Third Party's Issue
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

((<encode_params|URL:https://github.com/rails/rails/blob/3-2-stable/act...))

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
9361878d459f1709feec780518946ee5?d=identicon&s=25 naruse (Yui NARUSE) (Guest)
on 2013-10-10 03:56
(Received via mailing list)
Issue #8995 has been updated by naruse (Yui NARUSE).


なかださんの指摘の通り、
> return params.force_encoding("UTF-8").encode!
の行は何がしたいのかよくわかりませんね。
本当は
> return params.force_encoding("UTF-16").encode!
とやって、まさに Ruby 2.1 の挙動にしたかったのかな。

結論もなかださんの仰るとおり、
バイナリデータフラグを加えるか、ASCII-8BITで流すかあたりになるんじゃないかと思います。
----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995#change-42402

Author: hsbt (Hiroshi SHIBATA)
Status: Third Party's Issue
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

((<encode_params|URL:https://github.com/rails/rails/blob/3-2-stable/act...))

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (nobu)
on 2013-11-23 03:35
(Received via mailing list)
Issue #8995 has been updated by nobu (Nobuyoshi Nakada).


workaroundが入ったようですが、元々UTF-8ではないバイナリデータが壊れないということは、裏を返せばmalformed
UTF-8の攻撃文字列も破棄されないということです。
つまり、脆弱性はそのまま残っているわけなので、何らかの対策が必要であろうことだけは警告しておきます。
----------------------------------------
Bug #8995: バイナリデータを文字列として encode! すると readbyte の結果が変化する
https://bugs.ruby-lang.org/issues/8995#change-43098

Author: hsbt (Hiroshi SHIBATA)
Status: Third Party's Issue
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Rails の以下のコードの結果が 2.0 と 2.1 とで異なるようです。

((<encode_params|URL:https://github.com/rails/rails/blob/3-2-stable/act...))

以下が最小ケースです。

 $ ruby -v
 => ruby 2.1.0dev (2013-10-07 trunk 43160) [x86_64-darwin12.5.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 239

なお、2.0 ではそれぞれの値が変化しませんでした。

 $ ruby -v
 => ruby 2.0.0p326 (2013-10-05 revision 43144) [x86_64-darwin13.0.0]
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg')).readbyte"
 => 255
 $ ruby -rstringio -e "Encoding.default_internal = Encoding::UTF_8; p
StringIO.new(File.read('x.jpg').force_encoding('UTF-8').encode\!).readbyte"
 => 255

rails の該当箇所は rails4 でも同じ処理を行っているので、このままだと post で画像などを送るともれなく壊れてしまいます。

rails のコードがよくないのか、File.binread を使って読み込んでないのがおかしいなど教えて頂けると嬉しいです。

=end
This topic is locked and can not be replied to.