22layout: default
33title: Security
44---
5-
6- Translated by Clifford Escobar CAOILE
5+ Translated by Clifford Escobar CAOILE & ocha-
76
87h1. Chapter 7: Security
98
@@ -29,10 +28,10 @@ groups:
2928* Dangerous code
3029
3130For the former, the code that handles these values is created by the
32- programmers themselves, so therefore it is (pretty ) safe. For the latter, the
33- program code absolutely cannot be trusted.
31+ programmers themselves, so therefore it is (relatively ) safe. For the latter,
32+ the program code absolutely cannot be trusted.
3433
35- Because for these causes the solution is vastly different, it is important to
34+ Because the solution is vastly different between the two causes , it is important to
3635differentiate them by level. This are called security levels. The Ruby security
3736level is represented by the `$SAFE` global variable. The value ranges from
3837minimum value 0 to maximum value 4. When the variable is assigned, the level
@@ -44,28 +43,32 @@ Level 0 is the normal program environment and the security system is not
4443running. Level 2 handles dangerous values. Level 4 handles dangerous code.
4544We can skip 0 and move on to explain in detail levels 2 and 4.
4645
47- h4. Level 2
46+ ((errata: Level 1 handles dangerous values.
47+ "Level 2 has no use currently" is right.))
48+
49+
50+ h4. Level 1
4851
4952This level is for dangerous data, for example, in normal CGI
5053applications, etc.
5154
52- A per-object "dirty mark" serves as the basis for the Level 2
53- implementation. All objects read in externally are marked dirty , and
54- any attempt to `eval` or `File.open` with a dirty object will cause an
55+ A per-object "tainted mark" serves as the basis for the Level 1
56+ implementation. All objects read in externally are marked tainted , and
57+ any attempt to `eval` or `File.open` with a tainted object will cause an
5558exception to be raised and the attempt will be stopped.
5659
57- This dirty mark is "infectious". For example, when taking a part of a
58- dirty string, that part is also dirty .
60+ This tainted mark is "infectious". For example, when taking a part of a
61+ tainted string, that part is also tainted .
5962
6063h4. Level 4
6164
6265This level is for dangerous programs, for example, running external
6366(unknown) programs, etc.
6467
65- At level 2 , operations and the data it uses are checked, but at level
68+ At level 1 , operations and the data it uses are checked, but at level
66694, operations themselves are restricted. For example, `exit`, file
6770I/O, thread manipulation, redefining methods, etc. Of course, the
68- dirty mark information is used, but basically the operations are the
71+ tainted mark information is used, but basically the operations are the
6972criteria.
7073
7174h4. Unit of Security
@@ -93,10 +96,10 @@ p($SAFE) # Outside of the block, the level is still 0
9396
9497h4. Reliability of `$SAFE`
9598
96- Even with implementing the spreading of dirty marks, or restricting
99+ Even with implementing the spreading of tainted marks, or restricting
97100operations, ultimately it is still handled manually. In other words,
98101internal libraries and external libraries must be completely
99- compatible and if they don't, then the partway the "dirty " operations
102+ compatible and if they don't, then the partway the "tainted " operations
100103will not spread and the security will be lost. And actually this kind
101104of hole is often reported. For this reason, this writer does not
102105wholly trust it.
@@ -111,37 +114,49 @@ is common sense that adding new features can make holes easier to
111114open. Therefore it is prudent to think that `ruby` can probably be
112115dangerous.
113116
114- h3. 実装
115117
116- ここからは実装に入るが、`ruby`のセキュリティシステムを完全に捉えるに
117- は仕組みよりもむしろ「どこをチェックしているのか」を見なければならない。
118- しかし今回それをやっているページはないし、いちいちリストアップするだけ
119- では面白くない。そこでとりあえずこの章ではセキュリティチェックに使わ
120- れる仕組みだけを解説して終えることにする。チェック用のAPIは主に以下の
121- 二つだ。
118+ h3. Implementation
119+
120+
121+ From now on, we'll start to look into its implementation.
122+ In order to wholly grasp the security system of `ruby`,
123+ we have to look at "where is being checked" rather than its mechanism.
124+ However, this time we don't have enough pages to do it,
125+ and just listing them up is not interesting.
126+ Therefore, in this chapter, I'll only describe about the
127+ mechanism used for security checks.
128+ The APIs to check are mainly these below two:
129+
130+
131+ * `rb_secure(n)` : If more than or equal to level n, it would raise `SecurityError`.
132+ * `SafeStringValue()` :
133+ If more than or equal to level 1 and a string is tainted,
134+ then it would raise an exception.
122135
123- * レベル n 以上なら例外`SecurityError`を発生する`rb_secure(n)`
124- * レベル1以上のとき、文字列が汚染されていたら例外を発生する`SafeStringValue()`
125136
126- `SafeStringValue()`はここでは読まない。
137+ We won't read `SafeStringValue()` here.
127138
128- h4. 汚染マーク
129139
130- 汚染マークとは具体的には`basic->flags`に記憶される
131- フラグ`FL_TAINT`で、
132- それを感染させるのは`OBJ_INFECT()`というマクロである。
133- このように使う。
140+ h4. Tainted Mark
141+
142+
143+ The taint mark is, to be concrete, the `FL_TAINT` flag, which is set to
144+ `basic->flags`, and what is used to infect it is the `OBJ_INFECT()` macro.
145+ Here is its usage.
146+
134147
135148<pre class="emlist">
136- OBJ_TAINT(obj) /* objにFL_TAINTを付ける */
137- OBJ_TAINTED(obj) /* objにFL_TAINTが付いているか調べる */
138- OBJ_INFECT(dest, src) /* srcからdestにFL_TAINTを伝染させる */
149+ OBJ_TAINT(obj) /* set FL_TAINT to obj */
150+ OBJ_TAINTED(obj) /* check if FL_TAINT is set to obj */
151+ OBJ_INFECT(dest, src) /* infect FL_TAINT from src to dest */
139152</pre>
140153
141- `OBJ_TAINT()`・`OBJ_TAINTED()`はどうでもいいとして、
142- `OBJ_INFECT()`だけさっと見よう。
143154
144- ▼ `OBJ_INFECT`
155+ Since `OBJ_TAINT()` and `OBJ_TAINTED()` can be assumed not important,
156+ let's briefly look over only `OBJ_INFECT()`.
157+
158+
159+ <p class="caption">▼ `OBJ_INFECT` </p>
145160<pre class="longlist">
146161 441 #define OBJ_INFECT(x,s) do { \
147162 if (FL_ABLE(x) && FL_ABLE(s)) \
@@ -151,13 +166,18 @@ OBJ_INFECT(dest, src) /* srcからdestにFL_TAINTを伝染させる */
151166(ruby.h)
152167</pre>
153168
154- `FL_ABLE()`は引数の`VALUE`がポインタであるかどうか調べる。
155- 両方のオブジェクトがポインタなら(つまり`flags`メンバがあるなら)、
156- フラグを伝播する。
157169
158- h4. `$SAFE`
170+ `FL_ABLE()` checks if the argument `VALUE` is a pointer or not.
171+ If the both objects are pointers (it means each of them has its `flags` member),
172+ it would propagate the flag.
173+
159174
160- ▼ `ruby_safe_level`
175+
176+
177+ h4. $SAFE
178+
179+
180+ <p class="caption">▼ `ruby_safe_level` </p>
161181<pre class="longlist">
162182 124 int ruby_safe_level = 0;
163183
@@ -178,21 +198,31 @@ h4. `$SAFE`
178198(eval.c)
179199</pre>
180200
181- `$SAFE`の実体は`eval.c`の`ruby_safe_level`だ。先に書いたとおり
182- `$SAFE`は
183- スレッドに固有なので、スレッドの実装がある`eval.c`に書く必要があったからだ。
184- つまりC言語の都合で`eval.c`にあるだけで、本来は別の場所にあってよい。
185201
186- `safe_setter()`はグローバル変数`$SAFE`の`setter`である。
187- つまりRubyレベルからはこの関数経由でしかアクセスできないので
188- レベルを下げることはできなくなる。
202+ The substance of `$SAFE` is `ruby_safe_level` in `eval.c`.
203+ As I previously wrote, `$SAFE` is local to each thread,
204+ It needs to be written in `eval.c` where the implementation of threads is located.
205+ In other words, it is in `eval.c` only because of the restrictions of C,
206+ but it can essentially be located in another place.
207+
208+
209+ `safe_setter()` is the `setter` of the `$SAFE` global variable.
210+ It means, because this function is the only way to access it from Ruby level,
211+ the security level cannot be lowered.
212+
213+
214+ However, as you can see, from C level,
215+ because `static` is not attached to `ruby_safe_level`,
216+ you can ignore the interface and modify the security level.
217+
218+
219+
189220
190- ただし見てのとおり`ruby_safe_level`には`static`が付いていないので
191- Cレベルからはインターフェイスを無視してセキュリティレベルを変更できる。
192221
193222h4. `rb_secure()`
194223
195- ▼ `rb_secure()`
224+
225+ <p class="caption">▼ `rb_secure()` </p>
196226<pre class="longlist">
197227 136 void
198228 137 rb_secure(level)
@@ -207,5 +237,6 @@ h4. `rb_secure()`
207237(eval.c)
208238</pre>
209239
210- 現在のセーフレベルが`level`以上だったら例外`SecurityError`を発生。簡単だ。
211240
241+ If the current safe level is more than or equal to `level`,
242+ this would raise `SecurityError`. It's simple.
0 commit comments