[Ruby 1.9 - Bug #5279][Open] String#encode may raise SecurityError when $SAFE >= 3

44469 Shota Fukumori <sorah tubusu.net> (2011-09-06 09:39:09 +0900) [Ruby 1.9 - Bug #5279][Open] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

Issue #5279 has been reported by Shota Fukumori.

----------------------------------------
Bug #5279: 
http://redmine.ruby-lang.org/issues/5279

Author: Shota Fukumori
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 
ruby -v: ruby 1.9.4dev (2011-09-05 trunk 33195) [x86_64-darwin11.1.0] 


This is sora_h.

I investigated the problem @hsbt tweeted on twitter.
http://twitter.com/#!/hsbt/status/110700488667832320
[translation of the tweet : @sora_h I'm looking for the reason or resource (document or specification) that String#encode raises SecurityError with $SAFE=4.]

From what I found, String#encode calls require inside of it. When the safe level is 3 or higher, all objects are tainted and rb_require raises SecurityError because the String given to rb_require_safe is tainted.

So this code raises SecurityError:

    $SAFE = 3
    "a".encode("UTF-16")

while the following one does not.

    "a".encode("UTF-16")
    $SAFE = 3
    "a".encode("UTF-16")

I wrote a patch to fix this (pasted on the end of the ticket), but I'm not sure that passing 0 to rb_require_safe as its second argument is OK.
Since this is a security issue, I'd like to commit after we get a consensus or fix any problems with the patch and get a consensus.

The patch is as follows:

diff --git a/ChangeLog b/ChangeLog
index a16e823..07f76a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Sep  6 08:56:06 2011  Shota Fukumori  <sorah / tubusu.net>
+
+       * transcode.c: Use rb_require_safe() to load transcoder.
+         Because if $SAFE is higher than 3, rb_require() raises SecurityError.
+
 Mon Sep  5 20:59:30 2011  CHIKANAGA Tomoyuki  <nagachika00 / gmail.com>

        * insns.def: change encoding pragma for emacs (shift_jis to utf-8).
diff --git a/transcode.c b/transcode.c
index 2c188b6..0651aec 100644
--- a/transcode.c
+++ b/transcode.c
@@ -375,7 +375,7 @@ load_transcoder_entry(transcoder_entry_t *entry)
             return NULL;
         memcpy(path, transcoder_lib_prefix, sizeof(transcoder_lib_prefix) - 1);
         memcpy(path + sizeof(transcoder_lib_prefix) - 1, lib, len + 1);
-        if (!rb_require(path))
+        if (!rb_require_safe(rb_str_new2(path), 0))
             return NULL;
     }


-- 
http://redmine.ruby-lang.org

Refine translation / View logs (2)
Issue #5279 has been reported by Shota Fukumori.

---(click to toggle ticket description)---
Bug #5279: $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある
http://redmine.ruby-lang.org/issues/5279

Author: Shota Fukumori
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 
ruby -v: ruby 1.9.4dev (2011-09-05 trunk 33195) [x86_64-darwin11.1.0] 


sora_hです.

twitter
で @hsbt さんがこのような事を言っていたので調査してみました:
http://twitter.com/#!/hsbt/status/110700488667832320

調査したところ,どうやらString#encodeは内部的にrequireしていて,
セーフレベル3から全てのオブジェクトが汚染されるので,rb_require_safeに渡るStringが汚染されるため,
rb_requireでSecurityErrorが発生します.

なので,以下の場合はSecurityErrorが発生しますが,

    $SAFE = 3
    "a".encode("UTF-16")

以下の場合は発生しません.

    "a".encode("UTF-16")
    $SAFE = 3
    "a".encode("UTF-16")

これを修正するパッチを書いてみましたが(チケット末尾に貼り付け),
果たしてrb_require_safeの第二引数に0を渡しても問題ないのか自信がありません.
これはセキュリティ周りの問題なので,合意を取ってからコミット,もしくはパッチに
含む問題を修正し合意が取れてからコミットしようと思います.

以下patch

diff --git a/ChangeLog b/ChangeLog
index a16e823..07f76a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Sep  6 08:56:06 2011  Shota Fukumori  <sorah / tubusu.net>
+
+       * transcode.c: Use rb_require_safe() to load transcoder.
+         Because if $SAFE is higher than 3, rb_require() raises SecurityError.
+
 Mon Sep  5 20:59:30 2011  CHIKANAGA Tomoyuki  <nagachika00 / gmail.com>

        * insns.def: change encoding pragma for emacs (shift_jis to utf-8).
diff --git a/transcode.c b/transcode.c
index 2c188b6..0651aec 100644
--- a/transcode.c
+++ b/transcode.c
@@ -375,7 +375,7 @@ load_transcoder_entry(transcoder_entry_t *entry)
             return NULL;
         memcpy(path, transcoder_lib_prefix, sizeof(transcoder_lib_prefix) - 1);
         memcpy(path + sizeof(transcoder_lib_prefix) - 1, lib, len + 1);
-        if (!rb_require(path))
+        if (!rb_require_safe(rb_str_new2(path), 0))
             return NULL;
     }


-- 
http://redmine.ruby-lang.org

44470 Kenta Murata <muraken gmail.com> (2011-09-06 10:51:05 +0900) [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

Issue #5279 has been updated by Kenta Murata.


I think the point is not "Is it OK to passing 0 to rb_require_safe as its second argument", but "Is it OK to change the safe level to 0 temporarily in the transcoder".
Refine translation
Issue #5279 has been updated by Kenta Murata.


「rb_require_safe の第2引数に0を渡して良いかどうか」が問題なのではなく、
「transcoder の中で一時的に safe level を0に戻して良いかどうか」が問題なのではないでしょうか。
---(click to toggle ticket description)---
Bug #5279: $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある
http://redmine.ruby-lang.org/issues/5279

Author: Shota Fukumori
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 
ruby -v: ruby 1.9.4dev (2011-09-05 trunk 33195) [x86_64-darwin11.1.0] 


sora_hです.

twitter
で @hsbt さんがこのような事を言っていたので調査してみました:
http://twitter.com/#!/hsbt/status/110700488667832320

調査したところ,どうやらString#encodeは内部的にrequireしていて,
セーフレベル3から全てのオブジェクトが汚染されるので,rb_require_safeに渡るStringが汚染されるため,
rb_requireでSecurityErrorが発生します.

なので,以下の場合はSecurityErrorが発生しますが,

    $SAFE = 3
    "a".encode("UTF-16")

以下の場合は発生しません.

    "a".encode("UTF-16")
    $SAFE = 3
    "a".encode("UTF-16")

これを修正するパッチを書いてみましたが(チケット末尾に貼り付け),
果たしてrb_require_safeの第二引数に0を渡しても問題ないのか自信がありません.
これはセキュリティ周りの問題なので,合意を取ってからコミット,もしくはパッチに
含む問題を修正し合意が取れてからコミットしようと思います.

以下patch

diff --git a/ChangeLog b/ChangeLog
index a16e823..07f76a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Sep  6 08:56:06 2011  Shota Fukumori  <sorah / tubusu.net>
+
+       * transcode.c: Use rb_require_safe() to load transcoder.
+         Because if $SAFE is higher than 3, rb_require() raises SecurityError.
+
 Mon Sep  5 20:59:30 2011  CHIKANAGA Tomoyuki  <nagachika00 / gmail.com>

        * insns.def: change encoding pragma for emacs (shift_jis to utf-8).
diff --git a/transcode.c b/transcode.c
index 2c188b6..0651aec 100644
--- a/transcode.c
+++ b/transcode.c
@@ -375,7 +375,7 @@ load_transcoder_entry(transcoder_entry_t *entry)
             return NULL;
         memcpy(path, transcoder_lib_prefix, sizeof(transcoder_lib_prefix) - 1);
         memcpy(path + sizeof(transcoder_lib_prefix) - 1, lib, len + 1);
-        if (!rb_require(path))
+        if (!rb_require_safe(rb_str_new2(path), 0))
             return NULL;
     }


-- 
http://redmine.ruby-lang.org

44471 Shota Fukumori <sorah tubusu.net> (2011-09-06 11:02:00 +0900) [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

Issue #5279 has been updated by Shota Fukumori.

I think that covers it pretty well. We talked about temporarily changing the safe level to 0 inside of transcoder on #ruby-ja. The results from that were that autoload loads the contents according to the safe level from where it (autoload) is defined, so if $SAFE=0 to begin with and you then apply autoload to perform the interpreting (the system is totally different, but that aside) then there's no problem.

What we're worried about is that it may be possible to pass something in via require path from the script side; to my knowledge this can't be done but if it was possible for some reason then passing 0 as the second argument to rb_require_safe would be dangerous and that would not be the correct way to fix it.
Refine translation
Issue #5279 has been updated by Shota Fukumori.


中身的にはそういう事ですね. < transcoder の中で一時的に safe level を 0

#ruby-ja で議論したところ,autoloadはautoloadを定義した場所のSAFEで読み込むので,
$SAFE=0のときにあらかじめautoloadを仕掛けておいたというような解釈(仕組みな全然違いますが)
をすれば別に問題ないのではないか,という感じでした.

懸念しているのはrequireのpathにスクリプトサイドから自分でパスを流す事ができるかできないかで,
自分の認識ではできないと思っているのですが,もし可能だとするとrb_require_safeの第二引数に0を
渡すのは危険なのでこの修正方法じゃダメだと思っています.
---(click to toggle ticket description)---
Bug #5279: $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある
http://redmine.ruby-lang.org/issues/5279

Author: Shota Fukumori
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 
ruby -v: ruby 1.9.4dev (2011-09-05 trunk 33195) [x86_64-darwin11.1.0] 


sora_hです.

twitter
で @hsbt さんがこのような事を言っていたので調査してみました:
http://twitter.com/#!/hsbt/status/110700488667832320

調査したところ,どうやらString#encodeは内部的にrequireしていて,
セーフレベル3から全てのオブジェクトが汚染されるので,rb_require_safeに渡るStringが汚染されるため,
rb_requireでSecurityErrorが発生します.

なので,以下の場合はSecurityErrorが発生しますが,

    $SAFE = 3
    "a".encode("UTF-16")

以下の場合は発生しません.

    "a".encode("UTF-16")
    $SAFE = 3
    "a".encode("UTF-16")

これを修正するパッチを書いてみましたが(チケット末尾に貼り付け),
果たしてrb_require_safeの第二引数に0を渡しても問題ないのか自信がありません.
これはセキュリティ周りの問題なので,合意を取ってからコミット,もしくはパッチに
含む問題を修正し合意が取れてからコミットしようと思います.

以下patch

diff --git a/ChangeLog b/ChangeLog
index a16e823..07f76a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Sep  6 08:56:06 2011  Shota Fukumori  <sorah / tubusu.net>
+
+       * transcode.c: Use rb_require_safe() to load transcoder.
+         Because if $SAFE is higher than 3, rb_require() raises SecurityError.
+
 Mon Sep  5 20:59:30 2011  CHIKANAGA Tomoyuki  <nagachika00 / gmail.com>

        * insns.def: change encoding pragma for emacs (shift_jis to utf-8).
diff --git a/transcode.c b/transcode.c
index 2c188b6..0651aec 100644
--- a/transcode.c
+++ b/transcode.c
@@ -375,7 +375,7 @@ load_transcoder_entry(transcoder_entry_t *entry)
             return NULL;
         memcpy(path, transcoder_lib_prefix, sizeof(transcoder_lib_prefix) - 1);
         memcpy(path + sizeof(transcoder_lib_prefix) - 1, lib, len + 1);
-        if (!rb_require(path))
+        if (!rb_require_safe(rb_str_new2(path), 0))
             return NULL;
     }


-- 
http://redmine.ruby-lang.org

44472 "NARUSE, Yui" <naruse airemix.jp> (2011-09-06 11:52:19 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

From what I see this 'path' is taken from transcoder_entry_t, but as far as where this 'entry' is made, it's normally done in rb_declare_transcoder. So, as to where this is called from, in transdb.h it's called with a string that was fixed at build time. Therefore I think it's safe. (Of course if it's jumped into from the C API then these restrictions might not apply.)

-- 
NARUSE, Yui  <naruse / airemix.jp>

Refine translation
2011年9月6日11:02 Shota Fukumori <sorah / tubusu.net>:
> 懸念しているのはrequireのpathにスクリプトサイドから自分でパスを流す事ができるかできないかで,
> 自分の認識ではできないと思っているのですが,もし可能だとするとrb_require_safeの第二引数に0を
> 渡すのは危険なのでこの修正方法じゃダメだと思っています.

見れば分かる通りこの path は transcoder_entry_t から取り出されているわけですが、
この entry がどこで作られているかというと、rb_declare_transcoder で通常作られます。
で、こいつはどこから呼ばれるかというと、transdb.h からビルド時に決定される
固定文字列で呼ばれます。
なので、安全だと考えています。
(もちろん C API たたいて横から割り込んだ時はこの限りではない)

-- 
NARUSE, Yui  <naruse / airemix.jp>

44473 "Shota Fukumori (sora_h)" <sorah tubusu.net> (2011-09-06 13:10:00 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

Then it looks OK.

P.S.: For the test cases of this bug, I'm writing them now.

2011/9/6 NARUSE, Yui <naruse / airemix.jp>:
> So I think it is safe.
> (Of cource it is not when it is intercepted with C API)


-- 
Shota Fukumori a.k.a. @sora_h - http://sorah.jp/

Refine translation
じゃぁ,大丈夫かな.

P.S.: このバグについてのテストケースは今書いています.

2011/9/6 NARUSE, Yui <naruse / airemix.jp>:
> なので、安全だと考えています。
> (もちろん C API たたいて横から割り込んだ時はこの限りではない)


-- 
Shota Fukumori a.k.a. @sora_h - http://sorah.jp/

44474 Kazuhiko <kazuhiko fdiary.net> (2011-09-06 19:10:12 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

It is fixed in r33201. Are you going to backport it to the 1.9.3 branch?

--
Kazuhiko

Refine translation
On 06/09/2011 06:10, Shota Fukumori (sora_h) wrote:
> じゃぁ,大丈夫かな.
> 
> P.S.: このバグについてのテストケースは今書いています.
> 
> 2011/9/6 NARUSE, Yui <naruse / airemix.jp>:
>> なので、安全だと考えています。
>> (もちろん C API たたいて横から割り込んだ時はこの限りではない)

r33201 で修正されましたが、これは1.9.3ブランチにバックポートされますか?

かずひこ

44475 "Shota Fukumori (sora_h)" <sorah tubusu.net> (2011-09-06 19:14:58 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

I'm sora_h.

On Sep 6, 2011 7:12 PM, "Kazuhiko" <kazuhiko / fdiary.net> wrote:
> It is fixed in r33201. Are you going to backport it to the 1.9.3 branch?

I think it should be, but there is no Backport93 project yet...
Who is in charge of backporting now?

Refine translation
--20cf3079bcb258164a04ac43191e
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

sora_h です。

On Sep 6, 2011 7:12 PM, "Kazuhiko" <kazuhiko / fdiary.net> wrote:
> r33201 で気気譴泙靴燭�△海譴�窺庚ぢブランチにバックポートされますか?

されるべきだと思います。まだBackport93プロジェクトはないのか。。。
いま誰がバックポート担当してるんでしょう。

--20cf3079bcb258164a04ac43191e
Content-Type: text/html; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

<p>sora_h です。</p>
<p>On Sep 6, 2011 7:12 PM, &quot;Kazuhiko&quot; &lt;<a hrefailto:kazuhiko / fdiary.net">kazuhiko / fdiary.net</a>&gt; wrote:<br>
&gt; r33201 で気気譴泙靴燭�△海譴�窺庚ぢブランチにバックポートされますか?</p>
<p>されるべきだと思います。まだBackport93プロジェクトはないのか。。。 <br>
いま誰がバックポート担当してるんでしょう。</p>

--20cf3079bcb258164a04ac43191e--

44478 KOSAKI Motohiro <kosaki.motohiro gmail.com> (2011-09-06 23:55:05 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

2011-09-06 19:14 Shota Fukumori (sora_h) <sorah / tubusu.net>:
> I think it should be, but there is no Backport93 project yet...


It seems to be exist:

http://redmine.ruby-lang.org/projects/ruby-193

Refine translation
2011年9月6日19:14 Shota Fukumori (sora_h) <sorah / tubusu.net>:
> sora_h です。
>
> On Sep 6, 2011 7:12 PM, "Kazuhiko" <kazuhiko / fdiary.net> wrote:
>> r33201 で修正されましたが、これは1.9.3ブランチにバックポートされますか?
>
> されるべきだと思います。まだBackport93プロジェクトはないのか。。。
> いま誰がバックポート担当してるんでしょう。

あるように見えるけど?

http://redmine.ruby-lang.org/projects/ruby-193

44480 "Shota Fukumori (sora_h)" <sorah tubusu.net> (2011-09-07 07:30:19 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

Oh, that's right. Thanks.
Refine translation
あれれ,ほんとだ.失礼.

2011/9/6 KOSAKI Motohiro <kosaki.motohiro / gmail.com>:
> あるように見えるけど?
>
> http://redmine.ruby-lang.org/projects/ruby-193

-- 
Shota Fukumori a.k.a. @sora_h - http://sorah.jp/

44481 "Shota Fukumori (sora_h)" <sorah tubusu.net> (2011-09-07 07:45:10 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

I found Kazuhiko-san created a ticket for backporting as #5286.
Who can backport it now? yugui-san?
http://redmine.ruby-lang.org/issues/5286

Refine translation
かずひこさんが #5286 でバックポートチケットを切っているみたいです.
今バックポートできるのは誰なんでしょう.yuguiさん?
http://redmine.ruby-lang.org/issues/5286

2011/9/7 Shota Fukumori (sora_h) <sorah / tubusu.net>:
> あれれ,ほんとだ.失礼.

-- 
Shota Fukumori a.k.a. @sora_h - http://sorah.jp/

44482 KOSAKI Motohiro <kosaki.motohiro gmail.com> (2011-09-07 08:10:15 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

It should not be backported to 1.9.3p0 because it is not a regression.
As it is one week before the release date, we should restrict backports to the  bugs like [Bug #5076] by which ruby does not work on certain supported platform at all, or a problem reported as regression like [ruby-core:39268].

Refine translation
> かずひこさんが #5286 でバックポートチケットを切っているみたいです.
> 今バックポートできるのは誰なんでしょう.yuguiさん?
> http://redmine.ruby-lang.org/issues/5286

regressionじゃないから1.9.3p0はだめ。リリース一週間前に緊急で入れていいのは
[Bug #5076] のようなプラットフォームサポートが全滅するんじゃないか。というような
バグとか、[ruby-core:39268] のようなregressionを報告されてるときに限るべき。

44541 Kazuhiko <kazuhiko fdiary.net> (2011-09-25 03:47:10 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

I'm Kazuhiko.

I noticed that it does not work with $SAFE=4, while it works with $SAFE=3.
Sorry to report it now as Yugui backported the fix to 1.9.3 branch and 1.9.3RC1is released.

The following is the result on 1.9.3RC1.

$ ruby1.9 -v
ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]

$ ruby1.9 -e '$SAFE=3;"a".encode("utf-16be")'
(no exception)

$ ruby1.9 -e '$SAFE=4;"a".encode("utf-16be")'
-e:1: warning: failed to load encoding (utf-16be); use ASCII-8BIT instead

$ ruby1.9 -e ' "a".encode("utf-16be");$SAFE=4;"a".encode("utf-16be")'
(no exception)

--
Kazuhiko

Refine translation
かずひこです。

On 06/09/2011 12:10, Kazuhiko wrote:
> On 06/09/2011 06:10, Shota Fukumori (sora_h) wrote:
>> じゃぁ,大丈夫かな.
>>
>> P.S.: このバグについてのテストケースは今書いています.
>>
>> 2011/9/6 NARUSE, Yui <naruse / airemix.jp>:
>>> なので、安全だと考えています。
>>> (もちろん C API たたいて横から割り込んだ時はこの限りではない)
> 
> r33201 で修正されましたが、これは1.9.3ブランチにバックポートされますか?

Yuguiさんが1.9.3ブランチにバックポートしてくださって、先ほどめでたく
1.9.3RC1が出た今ころになって気づいて、ものすごく申し訳ないのです
が、$SAFE=3の時は動くけれど、$SAFE=4だと相変わらず失敗するようです。

以下、1.9.3RC1での挙動です。

$ ruby1.9 -v
ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]

$ ruby1.9 -e '$SAFE=3;"a".encode("utf-16be")'
(no exception)

$ ruby1.9 -e '$SAFE=4;"a".encode("utf-16be")'
-e:1: warning: failed to load encoding (utf-16be); use ASCII-8BIT instead

$ ruby1.9 -e ' "a".encode("utf-16be");$SAFE=4;"a".encode("utf-16be")'
(no exception)

かずひこ

44549 KOSAKI Motohiro <kosaki.motohiro gmail.com> (2011-09-26 22:26:02 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

This was fixed in r33328; can it be put in 1.9.3? I'd like to hear your opinions. To be frank, I'm not really sure how important it is, but if we go with this it will be different in each of 1.9.[234], so I'm kind of torn about what I think.
Refine translation
> かずひこです。
>
> On 06/09/2011 12:10, Kazuhiko wrote:
>> On 06/09/2011 06:10, Shota Fukumori (sora_h) wrote:
>>> じゃぁ,大丈夫かな.
>>>
>>> P.S.: このバグについてのテストケースは今書いています.
>>>
>>> 2011/9/6 NARUSE, Yui <naruse / airemix.jp>:
>>>> なので、安全だと考えています。
>>>> (もちろん C API たたいて横から割り込んだ時はこの限りではない)
>>
>> r33201 で修正されましたが、これは1.9.3ブランチにバックポートされますか?
>
> Yuguiさんが1.9.3ブランチにバックポートしてくださって、先ほどめでたく
> 1.9.3RC1が出た今ころになって気づいて、ものすごく申し訳ないのです
> が、$SAFE=3の時は動くけれど、$SAFE=4だと相変わらず失敗するようです。
>
> 以下、1.9.3RC1での挙動です。
>
> $ ruby1.9 -v
> ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]
>
> $ ruby1.9 -e '$SAFE=3;"a".encode("utf-16be")'
> (no exception)
>
> $ ruby1.9 -e '$SAFE=4;"a".encode("utf-16be")'
> -e:1: warning: failed to load encoding (utf-16be); use ASCII-8BIT instead
>
> $ ruby1.9 -e ' "a".encode("utf-16be");$SAFE=4;"a".encode("utf-16be")'
> (no exception)

r33328 で直ったようですが、1.9.3に入れますか?みなさんの意見が聞きたいです。
正直ぼくのなかでは重要度は微妙なんですけど、このままだた1.9.[234] でそれぞれ
仕様が違うという事態になるので、それもいかがなものかと思い悩んでいます。

44554 Shugo Maeda <shugo ruby-lang.org> (2011-09-27 02:19:03 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

This is Maeda.

There is a sort of viable workaround available for this on the application level: If you want to allow use of something in the sandbox for $SAFE >= 4, then you can load the expression that you want to allow beforehand when $SAFE == 0. In the case of tDiary I think this is a realistic solution, so maybe we could take this into consideration when making a decision.

I believe that when $SAFE is 4 or above, you can't change the state of anything that is global; I'm a little concerned as I'm not sure if this goes against that rule or not. The effect of it is limited so I don't think it will cause any actual harm though.

As far as this being handled differently in each of 1.9.[234], I don't think we need to worry about it too much as I firmly believe that we need to get rid of $SAFE entirely in 2.0.

-- 
Shugo Maeda

Refine translation
前田です。

2011年9月26日22:26 KOSAKI Motohiro <kosaki.motohiro / gmail.com>:
>> Yuguiさんが1.9.3ブランチにバックポートしてくださって、先ほどめでたく
>> 1.9.3RC1が出た今ころになって気づいて、ものすごく申し訳ないのです
>> が、$SAFE=3の時は動くけれど、$SAFE=4だと相変わらず失敗するようです。
(snip)
> r33328 で直ったようですが、1.9.3に入れますか?みなさんの意見が聞きたいです。
> 正直ぼくのなかでは重要度は微妙なんですけど、このままだた1.9.[234] でそれぞれ
> 仕様が違うという事態になるので、それもいかがなものかと思い悩んでいます。

アプリケーション側のworkaroundとしては、$SAFE >= 4のサンドボックス内で
使用を許可したい変換表を$SAFE == 0のときにあらかじめロードしておくとい
う手があるので、tDiaryのケースでそれが現実的な解となるかどうかが、一つの
判断材料ですね。

$SAFEが4以上の時はグローバルな状態の変更が禁止されるという原則があった
と思うんですが、このケースはそれに抵触しないのかなというのがちょっと気に
なります。影響は限定的なので実害はない気がするのですが。

1.9.[234]で仕様が違うという点については、どうせ$SAFEは2.0で削除すべきだ
と思うので、あんまり気にしなくてもいいんじゃないでしょうか。

-- 
Shugo Maeda

44555 KOSAKI Motohiro <kosaki.motohiro gmail.com> (2011-09-27 10:25:49 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

[Translation not available]
Add translation
2011年9月27日2:19 Shugo Maeda <shugo / ruby-lang.org>:
> 前田です。
>
> 2011年9月26日22:26 KOSAKI Motohiro <kosaki.motohiro / gmail.com>:
>>> Yuguiさんが1.9.3ブランチにバックポートしてくださって、先ほどめでたく
>>> 1.9.3RC1が出た今ころになって気づいて、ものすごく申し訳ないのです
>>> が、$SAFE=3の時は動くけれど、$SAFE=4だと相変わらず失敗するようです。
> (snip)
>> r33328 で直ったようですが、1.9.3に入れますか?みなさんの意見が聞きたいです。
>> 正直ぼくのなかでは重要度は微妙なんですけど、このままだた1.9.[234] でそれぞれ
>> 仕様が違うという事態になるので、それもいかがなものかと思い悩んでいます。
>
> アプリケーション側のworkaroundとしては、$SAFE >= 4のサンドボックス内で
> 使用を許可したい変換表を$SAFE == 0のときにあらかじめロードしておくとい
> う手があるので、tDiaryのケースでそれが現実的な解となるかどうかが、一つの
> 判断材料ですね。
>
> $SAFEが4以上の時はグローバルな状態の変更が禁止されるという原則があった
> と思うんですが、このケースはそれに抵触しないのかなというのがちょっと気に
> なります。影響は限定的なので実害はない気がするのですが。
>
> 1.9.[234]で仕様が違うという点については、どうせ$SAFEは2.0で削除すべきだ
> と思うので、あんまり気にしなくてもいいんじゃないでしょうか。

なんと。そうだったのか。
話はそれてしまいますが、そろそろ2.0 (or 3.0) で消す予定のfeatureについて
w.r.o にwikiページつくりたいですね。
なんとなく、DLとsyckは代替ライブラリが出来たので消え行く運命なのかと思ってる。
ほかにも weakrefとか仕様レベルで問題があってメンテ不能なライブラリとか。

44559 Yuki Sonoda <yugui yugui.jp> (2011-09-27 21:23:43 +0900) [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

[Translation not available]
Add translation
Issue #5279 has been updated by Yuki Sonoda.


重要度は確かに微妙です。微妙なので、もはや仕様は完全に凍結するという原則論を優先します。何か現実的なセキュリティーホールに繋がる可能性があったら(DoS以外)また考えます
---(click to toggle ticket description)---
Bug #5279: $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある
http://redmine.ruby-lang.org/issues/5279

Author: Shota Fukumori
Status: Closed
Priority: Normal
Assignee: 
Category: 
Target version: 
ruby -v: -


sora_hです.

twitter
で @hsbt さんがこのような事を言っていたので調査してみました:
http://twitter.com/#!/hsbt/status/110700488667832320

調査したところ,どうやらString#encodeは内部的にrequireしていて,
セーフレベル3から全てのオブジェクトが汚染されるので,rb_require_safeに渡るStringが汚染されるため,
rb_requireでSecurityErrorが発生します.

なので,以下の場合はSecurityErrorが発生しますが,

    $SAFE = 3
    "a".encode("UTF-16")

以下の場合は発生しません.

    "a".encode("UTF-16")
    $SAFE = 3
    "a".encode("UTF-16")

これを修正するパッチを書いてみましたが(チケット末尾に貼り付け),
果たしてrb_require_safeの第二引数に0を渡しても問題ないのか自信がありません.
これはセキュリティ周りの問題なので,合意を取ってからコミット,もしくはパッチに
含む問題を修正し合意が取れてからコミットしようと思います.

以下patch

diff --git a/ChangeLog b/ChangeLog
index a16e823..07f76a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Sep  6 08:56:06 2011  Shota Fukumori  <sorah / tubusu.net>
+
+       * transcode.c: Use rb_require_safe() to load transcoder.
+         Because if $SAFE is higher than 3, rb_require() raises SecurityError.
+
 Mon Sep  5 20:59:30 2011  CHIKANAGA Tomoyuki  <nagachika00 / gmail.com>

        * insns.def: change encoding pragma for emacs (shift_jis to utf-8).
diff --git a/transcode.c b/transcode.c
index 2c188b6..0651aec 100644
--- a/transcode.c
+++ b/transcode.c
@@ -375,7 +375,7 @@ load_transcoder_entry(transcoder_entry_t *entry)
             return NULL;
         memcpy(path, transcoder_lib_prefix, sizeof(transcoder_lib_prefix) - 1);
         memcpy(path + sizeof(transcoder_lib_prefix) - 1, lib, len + 1);
-        if (!rb_require(path))
+        if (!rb_require_safe(rb_str_new2(path), 0))
             return NULL;
     }


-- 
http://redmine.ruby-lang.org

44560 Kazuhiko <kazuhiko fdiary.net> (2011-09-28 21:15:58 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

[Translation not available]
Add translation
かずひこです。

On 26/09/2011 19:19, Shugo Maeda wrote:
>>> Yuguiさんが1.9.3ブランチにバックポートしてくださって、先ほどめでたく
>>> 1.9.3RC1が出た今ころになって気づいて、ものすごく申し訳ないのです
>>> が、$SAFE=3の時は動くけれど、$SAFE=4だと相変わらず失敗するようです。
> (snip)
>> r33328 で直ったようですが、1.9.3に入れますか?みなさんの意見が聞きたいです。
>> 正直ぼくのなかでは重要度は微妙なんですけど、このままだた1.9.[234] でそれぞれ
>> 仕様が違うという事態になるので、それもいかがなものかと思い悩んでいます。
> 
> アプリケーション側のworkaroundとしては、$SAFE >= 4のサンドボックス内で
> 使用を許可したい変換表を$SAFE == 0のときにあらかじめロードしておくとい
> う手があるので、tDiaryのケースでそれが現実的な解となるかどうかが、一つの
> 判断材料ですね。

Yuguiさんの言うように、重要度は微妙というのには同意します。すくなくとも
tDiary的には、上記のワークアラウンドですでに回避できているので、まあ困ら
ないといえば困りません。

> $SAFEが4以上の時はグローバルな状態の変更が禁止されるという原則があった
> と思うんですが、このケースはそれに抵触しないのかなというのがちょっと気に
> なります。影響は限定的なので実害はない気がするのですが。

この修正の結果「グローバルな状態が変更される」のは、あくまでも(現状の)
実装の都合による副作用であって、それが理由でこの修正をrevertすることは無
いんじゃないかなと思います。
それはそれとして、1.9.3に対しては、タイミングが遅すぎたと思うので、「も
はや仕様は完全に凍結するという原則論を優先します」というYuguiさんの判断
に異論はありません。

> 1.9.[234]で仕様が違うという点については、どうせ$SAFEは2.0で削除すべきだ
> と思うので、あんまり気にしなくてもいいんじゃないでしょうか。

レンタルtDiaryの運営者としては、このissueそのものよりも↑こっちの方が気に
なります。:)

かずひこ

44572 Shugo Maeda <shugo ruby-lang.org> (2011-10-03 17:46:36 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

[Translation not available]
Add translation
前田です。

2011年9月28日21:15 Kazuhiko <kazuhiko / fdiary.net>:
>> 1.9.[234]で仕様が違うという点については、どうせ$SAFEは2.0で削除すべきだ
>> と思うので、あんまり気にしなくてもいいんじゃないでしょうか。
>
> レンタルtDiaryの運営者としては、このissueそのものよりも↑こっちの方が気に
> なります。:)

$SAFEは他の処理系でまったく実装されていないですし、サンドボックスとしても
中途半端なので、根本的に見直した方がよいと思っています。
が、合意が得られているわけではないので、結局2.0でも残ってしまうかもしれません。

tDiaryのプラグインについては、本来Rubyのコードをユーザに記述させる必要ない
と思うのですが、互換性的に記述方法を変えるのは難しいのでしょうね。
記法がある程度限定されていれば、自前でパースして、Rubyのコードとしてではなく
プラグイン処理だけ実行できるかもしれませんが…。

-- 
Shugo Maeda

44575 Kazuhiko <kazuhiko fdiary.net> (2011-10-04 19:02:02 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

[Translation not available]
Add translation
On 28/09/2011 14:15, Kazuhiko wrote:
> On 26/09/2011 19:19, Shugo Maeda wrote:
>>>> Yuguiさんが1.9.3ブランチにバックポートしてくださって、先ほどめでたく
>>>> 1.9.3RC1が出た今ころになって気づいて、ものすごく申し訳ないのです
>>>> が、$SAFE=3の時は動くけれど、$SAFE=4だと相変わらず失敗するようです。
>> (snip)
>>> r33328 で直ったようですが、1.9.3に入れますか?みなさんの意見が聞きたいです。
>>> 正直ぼくのなかでは重要度は微妙なんですけど、このままだた1.9.[234] でそれぞれ
>>> 仕様が違うという事態になるので、それもいかがなものかと思い悩んでいます。
>>
>> アプリケーション側のworkaroundとしては、$SAFE >= 4のサンドボックス内で
>> 使用を許可したい変換表を$SAFE == 0のときにあらかじめロードしておくとい
>> う手があるので、tDiaryのケースでそれが現実的な解となるかどうかが、一つの
>> 判断材料ですね。
> 
> Yuguiさんの言うように、重要度は微妙というのには同意します。すくなくとも
> tDiary的には、上記のワークアラウンドですでに回避できているので、まあ困ら
> ないといえば困りません。

えーと、さらに調査の結果、encodingによっては上記のワークアラウンドでうま
く動かないことがわかりました。

例えば、

$ ruby1.9 -ve 'a="あ";"あ".encode("euc-jp"); $SAFE=4; a.encode("euc-jp")'
ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]

↑これは動きますが、

$ ruby1.9 -ve 'a="あ";"".encode("euc-jp"); $SAFE=4; a.encode("euc-jp")'
ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]
-e:1:in `encode': Insecure operation - encode (SecurityError)
	from -e:1:in `<main>'

↑これは動きません。

この「あらかじめロードする」技が、対象となるStringと関係なく動くわけでは
ないとなれば、残念ながらワークアラウンドになりません。

なお、1.9.3RC1にr33328を適用すれば、もちろん無事に動きます。

というわけで、引き続き重要度が微妙なのは同意しますが、「レンタルtDiaryを
Ruby-1.9で動かしている数少ない管理人の一人」としては1.9.3に入ると嬉し
い、という感じです。

# とりあえず運用環境では1.9.3RC1にr33328を適用して動かすことにしました。

かずひこ

44576 "NARUSE, Yui" <naruse airemix.jp> (2011-10-04 19:22:22 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

[Translation not available]
Add translation
2011年10月4日19:02 Kazuhiko <kazuhiko / fdiary.net>:
> えーと、さらに調査の結果、encodingによっては上記のワークアラウンドでうま
> く動かないことがわかりました。
>
> 例えば、
>
> $ ruby1.9 -ve 'a="あ";"あ".encode("euc-jp"); $SAFE=4; a.encode("euc-jp")'
> ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]
>
> ↑これは動きますが、
>
> $ ruby1.9 -ve 'a="あ";"".encode("euc-jp"); $SAFE=4; a.encode("euc-jp")'
> ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]
> -e:1:in `encode': Insecure operation - encode (SecurityError)
>        from -e:1:in `<main>'
>
> ↑これは動きません。
>
> この「あらかじめロードする」技が、対象となるStringと関係なく動くわけでは
> ないとなれば、残念ながらワークアラウンドになりません。

空文字や ASCII 文字列はエンコーディング変換を要しないので変換ライブラリをロードしません。
なので、空文字では workaround にはなりません。
"\uFEFF".encode(enc) rescue nil
などとすれば任意のエンコーディングでいけるはずです。

-- 
NARUSE, Yui  <naruse / airemix.jp>

44577 Kazuhiko <kazuhiko fdiary.net> (2011-10-04 20:09:14 +0900) Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある

[Translation not available]
Add translation
On 04/10/2011 12:22, NARUSE, Yui wrote:
>> 例えば、
>>
>> $ ruby1.9 -ve 'a="あ";"あ".encode("euc-jp"); $SAFE=4; a.encode("euc-jp")'
>> ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]
>>
>> ↑これは動きますが、
>>
>> $ ruby1.9 -ve 'a="あ";"".encode("euc-jp"); $SAFE=4; a.encode("euc-jp")'
>> ruby 1.9.3dev (2011-09-23 revision 33323) [x86_64-linux]
>> -e:1:in `encode': Insecure operation - encode (SecurityError)
>>        from -e:1:in `<main>'
>>
>> ↑これは動きません。
>>
>> この「あらかじめロードする」技が、対象となるStringと関係なく動くわけでは
>> ないとなれば、残念ながらワークアラウンドになりません。
> 
> 空文字や ASCII 文字列はエンコーディング変換を要しないので変換ライブラリをロードしません。
> なので、空文字では workaround にはなりません。
> "\uFEFF".encode(enc) rescue nil
> などとすれば任意のエンコーディングでいけるはずです。

おぉ、素晴らしい。無事に回避できました。ありがとうございます。

かずひこ

Back