Hi all,
This is a summary of ruby-dev ML in these days.
Range: [ruby-dev:19878] … [ruby-dev:19943]
[ruby-dev:19865] dl in $SAFE=4
[ruby-list:37370] writing insecure programs
TANAKA Akira reported some additional vulnerabilities (refer
ChangeLog for details). At the same time, we re-confirmed
the security model of Ruby. Here is a short summary:
== Bases
Ruby’s security model is thread based.
Safe level (global variable $SAFE) is thread local.
== Safe level
==== Level 0
Normal state.
==== Level 1
Ruby prohibits dangerous operations using tainted objects.
Characteristic situations are CGI programs.
(handling untrusted DATA)
==== Level 2
Ruby prohibits changing global (process/environment) state.
e.g. chdir, chroot, mkdir, rmdir, stat, lstat, chmod, lchmod …
This level is not so useful.
==== Level 3
Ruby prohibits untainting objects.
Newly created objects are tainted.
You should use this level to set up environment for Level 4.
==== Level 4
Ruby prohibits all dangerous operations.
Level 4 programs also cannot modify untainted objects.
Characteristic situations are Ruby applets/plugins.
(handling untrusted CODE)
== Author’s perspective: Ruby extensions
If you are author of Ruby extensions, note following points:
* Check untrusted values by SafeStringValue().
e.g.
static VALUE
dangerous_operation(VALUE self, VALUE arg)
{
SafeStringValue(arg);
/* SafeStringValue() implicitly calls rb_secure(4) */
* Check untrusted code by rb_secure(4).
e.g.
static VALUE
dangerous_operation2(VALUE self)
{
rb_secure(4);
* Call rb_secure_update(obj) before updating OBJ, if OBJ is
under your control (ruby cannot handle it).
e.g.
static VALUE
update_local_state(VALUE self)
{
rb_secure_update(self);
GET_POINTER(self)->idx = INT2FIX(3);
* Transit object infection by OBJ_INFECT()/rb_obj_infect().
e.g.
static VALUE
normal_operation(VALUE self, VALUE str)
{
StringValue(str);
....
/* transit infection from STR to the created string */
return rb_obj_infect(rb_str_new(RSTRING(str)->ptr, len), str);
}
=== Security related C APIs
VALUE OBJ_INFECT(dest, src); /* Macro */
Taints DEST if SRC is tainted.
VALUE rb_obj_infect(dest, src); /* 1.8 only */
Taints DEST if SRC is tainted.
void SafeStringValue(VALUE lval); /* Macro, 1.8 only */
Converts LVAL into String and check if LVAL is dangerous.
If $SAFE>=4, raises SecurityError.
If LVAL is tainted and $SAFE>=1, raises SecurityError.
void rb_secure(int level);
Raises SecurityError if $SAFE>=level.
void rb_secure_update(obj); /* 1.8 only */
Raises SecurityError if $SAFE>=4 and OBJ is not tainted.
Finally, DO NOT TRUST Ruby’s safe level.
Ruby’s security model and its implementation is not mature.
There must be other hidden vulnerabilities.
[ruby-dev:19891] zlib (Re: dl in $SAFE=4)
UENO Katsuhiro imported Ruby/zlib into the main trunk.
You can get it from the cvs.ruby-lang.org:
$ cvs -d :pserver:anonymous@cvs.ruby-lang.org:/src login
Password: (anonymous)
$ cvs -d :pserver:anonymous@cvs.ruby-lang.org:/src co ruby
And Ruby/zlib is in the ext/zlib directory.
[ruby-dev:19912] Regular expression warning (Re: [Oniguruma] Version 1.8.4)
Ruby 1.8 warns about the bare ‘-’ in the character class:
% ruby-1.8.0 -e 're = /[-a-z]/'
-e:1: warning: character class has `-' without escape
TAKAHASHI Masayoshi suggested to suppress this warning,
if ‘-’ is the first/last character of the character class.
– Minero Aoki