Mod_ruby insecury op

[Wed Feb 12 12:00:16 2003] [error] mod_ruby: error in ruby
/tmp/showrun.rhtml.18210.0:54:in `exists?’: Insecure operation - exists?
(SecurityError)

and in my apache:

RubySafeLevel 0

offending line:
if (FileTest.exists?("#{dir}/#{d}/L1/magos.log"))

How am I supposed to check if a file exists or not?
Ideas?

db

···


Feb 12 Abraham Lincoln born, 1809
Feb 12 Charles Darwin born in Shrewsbury, England, 1809
Feb 12 Lincoln’s real birthday
Feb 12 Santa Barbara oil leak, 1969
Feb 12 Pyidaungsa Day in Burma
Feb 12 The Beatles play Carnegie Hall in New York City, 1964
Feb 12* Rosh Chodesh Adar (Beginning of the month of Adar)

Make sure the string isn’t tainted.

Chris

···

----- Original Message -----
From: “Daniel Bretoi” lists@debonair.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Wednesday, February 12, 2003 12:02 PM
Subject: mod_ruby insecury op

[Wed Feb 12 12:00:16 2003] [error] mod_ruby: error in ruby
/tmp/showrun.rhtml.18210.0:54:in `exists?’: Insecure operation - exists?
(SecurityError)

and in my apache:

RubySafeLevel 0

offending line:
if (FileTest.exists?("#{dir}/#{d}/L1/magos.log"))

How am I supposed to check if a file exists or not?
Ideas?

db


Feb 12 Abraham Lincoln born, 1809
Feb 12 Charles Darwin born in Shrewsbury, England, 1809
Feb 12 Lincoln’s real birthday
Feb 12 Santa Barbara oil leak, 1969
Feb 12 Pyidaungsa Day in Burma
Feb 12 The Beatles play Carnegie Hall in New York City, 1964
Feb 12* Rosh Chodesh Adar (Beginning of the month of Adar)

if (FileTest.exists?(“#{dir}/#{d}/L1/magos.log”))

I’m not familiar with Ruby’s safety level, but I would suppose that ‘dir’
and ‘d’ are tainted. I imagine that you are getting those from outside.

Untaint them first.

···

On Thu, Feb 13, 2003 at 05:02:56AM +0900, Daniel Bretoi wrote:

[Wed Feb 12 12:00:16 2003] [error] mod_ruby: error in ruby
/tmp/showrun.rhtml.18210.0:54:in `exists?': Insecure operation - exists?
(SecurityError)

and in my apache:

RubySafeLevel 0

offending line:
if (FileTest.exists?(“#{dir}/#{d}/L1/magos.log”))

How am I supposed to check if a file exists or not?
Ideas?

db


Feb 12 Abraham Lincoln born, 1809
Feb 12 Charles Darwin born in Shrewsbury, England, 1809
Feb 12 Lincoln’s real birthday
Feb 12 Santa Barbara oil leak, 1969
Feb 12 Pyidaungsa Day in Burma
Feb 12 The Beatles play Carnegie Hall in New York City, 1964
Feb 12* Rosh Chodesh Adar (Beginning of the month of Adar)


Daniel Carrera
Graduate Teaching Assistant. Math Dept.
University of Maryland. (301) 405-5137

Thanks guys, this one stings me every time. What exactly does untaining
on the string do?

db

···

On Thu, Feb 13, 2003 at 05:05:51AM +0900, Chris Pine wrote:

Make sure the string isn’t tainted.

Chris

----- Original Message -----
From: “Daniel Bretoi” lists@debonair.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Wednesday, February 12, 2003 12:02 PM
Subject: mod_ruby insecury op

[Wed Feb 12 12:00:16 2003] [error] mod_ruby: error in ruby
/tmp/showrun.rhtml.18210.0:54:in `exists?': Insecure operation - exists?
(SecurityError)

and in my apache:

RubySafeLevel 0

offending line:
if (FileTest.exists?(“#{dir}/#{d}/L1/magos.log”))

How am I supposed to check if a file exists or not?
Ideas?

db


Feb 12 Abraham Lincoln born, 1809
Feb 12 Charles Darwin born in Shrewsbury, England, 1809
Feb 12 Lincoln’s real birthday
Feb 12 Santa Barbara oil leak, 1969
Feb 12 Pyidaungsa Day in Burma
Feb 12 The Beatles play Carnegie Hall in New York City, 1964
Feb 12* Rosh Chodesh Adar (Beginning of the month of Adar)


Feb 12 Abraham Lincoln born, 1809
Feb 12 Charles Darwin born in Shrewsbury, England, 1809
Feb 12 Lincoln’s real birthday
Feb 12 Santa Barbara oil leak, 1969
Feb 12 Pyidaungsa Day in Burma
Feb 12 The Beatles play Carnegie Hall in New York City, 1964
Feb 12* Rosh Chodesh Adar (Beginning of the month of Adar)

If you turn on safety, any data received from outside your program is
considered “tainted” (i.e. untrustworthy). Tainted data cannot be used to
affect your system. It has to be untainted.

Taintedness is a way to force you to take safety precautions that you
might otherwise forget.

In your example, suppose that you get ‘dir’ from a web interface. You ask
the user for a directory and you do something with it. A malicious user
could type:

#{rm -f *}

When you put that in your program you get “…#{rm -f *}…”. The
rm -f * gets called and all your files get deletted.

I’m sure that you can come up with worse things that a user could do.

To untaint data you use regular expressions. In this case a directory
name should only be composed of “word” charcaters and the character “/”.

Do something like:

dir tainted.

if dir =~ /^([\w/]+)$/
dir = $1 # Untainted.
else
# Error…
end

Cheers,

···

On Thu, Feb 13, 2003 at 05:51:31AM +0900, Daniel Bretoi wrote:

Thanks guys, this one stings me every time. What exactly does untaining
on the string do?

db


Daniel Carrera
Graduate Teaching Assistant. Math Dept.
University of Maryland. (301) 405-5137

Thanks guys, this one stings me every time. What exactly does untaining
on the string do?

···

----- Original Message -----
From: “Daniel Bretoi” lists@debonair.net


The idea with tainting is that the string is considered “dangerous”…
probably you got it from the user (who could be trying to hack into your
machine).

Tainting is ‘sticky’, so if you have something like this:

safeString = 'hello, Daniel’
dangerString = ‘rm -rf *’

dangerString.taint

mixedString = safeString + dangerString

mixedString.tainted? # --> true

Ruby keeps close track of which strings are ‘pure’, and which are 'tainted’
by possible harmful data.

You should be very careful when using the `untaint’ method. For strings, I
usually run them through a regexp like /\A[\w\d]{3,20}\Z/ to make sure I
think they are ok. That regexp accepts strings of digits and letters from 3
to 20 characters in length. I always use \A and \Z (matching beginning and
end of whole string, not just of a line) when validating tainted strings.

Chris

[snip]

To untaint data you use regular expressions. In this case a directory
name should only be composed of “word” charcaters and the character “/”.

Do something like:

dir tainted.

if dir =~ /^([\w/]+)$/
dir = $1 # Untainted.
else
# Error…
end

···

----- Original Message -----
From: “Daniel Carrera” dcarrera@math.umd.edu


Cool! I didn’t know you could do that. I always just used `str.untaint’.

BTW, (to the original poster), tainting also bites me from time to time. So
far, though, it has always been a good thing! I feel safe at night
knowing that tainting is there.

:slight_smile:

Chris

Do something like:

Probably you make confusion with another language

# dir tainted.
if dir =~ /^([\w\/]+)$/
    dir = $1 # Untainted.
else
    # Error...
end

pigeon% cat b.rb
#!/usr/bin/ruby
dir = "aaa".taint
if dir =~ /^([\w\/]+)$/
   dir = $1
else
   raise "error"
end
p dir.tainted?
pigeon%

pigeon% b.rb
true
pigeon%

Guy Decoux

Do something like:

Probably you make confusion with another language

Actually no, I’m not.

Ruby’s taintedness behaves differently between internal and external data.
In your case, you were using internal data. In the web form example, I
was talking about external.

From PickAxe:

internal data

=============

x1 = “a string”
x1.tainted? # → false
x2 = x1[2, 4]
x2.tainted? # → false
x1 =~ /([a-z])/
$1.tainted? # → false

external data

=============

y1 = ENV[“HOME”]
y1.tainted? # → true
y2 = y1[2, 4]
y2.tainted? # → true
y1 =~ /([a-z])/
$1.tainted? # → true

···

pigeon% cat b.rb
#!/usr/bin/ruby
dir = “aaa”.taint
if dir =~ /^([\w/]+)$/
dir = $1
else
raise “error”
end
p dir.tainted?
pigeon%

pigeon% b.rb
true
pigeon%

Guy Decoux


Daniel Carrera
Graduate Teaching Assistant. Math Dept.
University of Maryland. (301) 405-5137

Do something like:

Probably you make confusion with another language

Actually no, I'm not.

From your previous message

To untaint data you use regular expressions. In this case a directory
name should only be composed of "word" charcaters and the character "/".

Do something like:

# dir tainted.
if dir =~ /^([\w\/]+)$/
    dir = $1 # Untainted.
else
    # Error...
end

Now see the result

# external data
# =============
y1 = ENV["HOME"]
y1.tainted? # -> true
y2 = y1[2, 4]
y2.tainted? # -> true
y1 =~ /([a-z])/
$1.tainted? # -> true

   ^^^^^^^^^^^^^^^^^^^^^^^^^^

  $1 is tainted

Guy Decoux

Ruby’s taintedness behaves differently between internal and external data.

···

----- Original Message -----
From: “Daniel Carrera” dcarrera@math.umd.edu


I don’t mean to be pedantic, but this isn’t really how I would say it.

The only thing Ruby does differently with external data is that it taints
it. Beyond that, Ruby makes no distinction. In other words, you could get
an external string, and it would be tainted, or you could just call
str.taint on an internal string; it does the same thing and Ruby deals with
it like it would any other tainted string.

That’s probably what you were saying, but I thought it might help the
original poster if I clarified.

Chris

No, I really do mean that they are different. Look at the examples I
gave. They are from PickAxe.

···

On Fri, Feb 14, 2003 at 04:45:43AM +0900, Chris Pine wrote:

----- Original Message -----
From: “Daniel Carrera” dcarrera@math.umd.edu

Ruby’s taintedness behaves differently between internal and external data.

I don’t mean to be pedantic, but this isn’t really how I would say it.

The only thing Ruby does differently with external data is that it taints
it. Beyond that, Ruby makes no distinction. In other words, you could get
an external string, and it would be tainted, or you could just call
str.taint on an internal string; it does the same thing and Ruby deals with
it like it would any other tainted string.

That’s probably what you were saying, but I thought it might help the
original poster if I clarified.


Daniel Carrera
Graduate Teaching Assistant. Math Dept.
University of Maryland. (301) 405-5137

I’m reading the Pickaxe p. 259 and for the life of me I cannot
understand why you’re saying they are different.

The examples show that tainted-ness is sticky, and that external data is
tainted. I don’t see the difference you’re talking about; I thus believe
Chris is right.

I’ve been especially slow today (caffeine didn’t help) so it could me
my fault, though :wink:

···

On Fri, Feb 14, 2003 at 05:25:13AM +0900, Daniel Carrera wrote:

On Fri, Feb 14, 2003 at 04:45:43AM +0900, Chris Pine wrote:

----- Original Message -----
From: “Daniel Carrera” dcarrera@math.umd.edu

Ruby’s taintedness behaves differently between internal and external data.

I don’t mean to be pedantic, but this isn’t really how I would say it.

The only thing Ruby does differently with external data is that it taints
it. Beyond that, Ruby makes no distinction. In other words, you could get
an external string, and it would be tainted, or you could just call
str.taint on an internal string; it does the same thing and Ruby deals with
it like it would any other tainted string.

That’s probably what you were saying, but I thought it might help the
original poster if I clarified.

No, I really do mean that they are different. Look at the examples I
gave. They are from PickAxe.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Checking host system type…
i586-unknown-linux
configure: error: sorry, this is the gnu os, not linux
– Topic on #Linux

I’m going to have to agree with Mauricio, who said I was right.

:wink:

seriously, though…

irb(main):001:0> x = ‘hello’.taint
"hello"
irb(main):002:0> x.tainted?
true
irb(main):003:0> y = x[2,4]
"llo"
irb(main):004:0> y.tainted?
true
irb(main):005:0> x =~ /([a-z])/
0
irb(main):006:0> $1.tainted?
true

This issue is not internal vs. external data. ‘hello’ was internal, but it
was tainted, and that’s what matters.

The only thing special about external data is that it is automatically
tainted. How Ruby deals with tainted data (regardless of whether it was
internal or external) is dependent upon your $SAFE level.

IIRC, external data is tainted even when $SAFE == 0, and tainting is still
contagious (or sticky, or whatever you want to call it), but none of Ruby’s
methods care if they are given tainted data or not. As $SAFE increases,
Ruby restricts more and more what you can do.

At least that’s how I think it works.

Chris

No, I really do mean that they are different. Look at the examples I
gave. They are from PickAxe.

I’m reading the Pickaxe p. 259 and for the life of me I cannot
understand why you’re saying they are different.

The examples show that tainted-ness is sticky, and that external data is
tainted. I don’t see the difference you’re talking about; I thus believe
Chris is right.

I’ve been especially slow today (caffeine didn’t help) so it could me
my fault, though :wink:

Well, actually I was being slow yesterday.
I misread what I saw in PickAxe. Even though I copied and pasted, I still
managed to read wrong. I think my mind played a trick on me, because I
thought that the second example said “true, true, false”.

So I apologize for my confusion. It seems that my brain will randomly
switch the words “true” and “false” in my head.

···


Daniel Carrera
Graduate Teaching Assistant. Math Dept.
University of Maryland. (301) 405-5137