Are you Tainted?
Ruby has a special method that you can call on an object called tainted?, and it will return a boolean based on whether the data comes from an external source or not. Values that come from the network, a file on disk, command line, etc. will be considered tainted. A value that is derived from inside your Ruby code will not.
irb> z = 20 + 50 => 70 irb> z.tainted? => false
irb> b = File.open("sample.txt").readlines.first
=> "This is an example text file.\n"
irb> b.tainted?
=> true
Even when you combine data from inside Ruby with tainted data you’ll still get something that’s tainted…
irb> n = b + " More text." => "This is an example text file.\n More text." irb> n.tainted? => true
One thing to note, and this is important, is that datastructures themselves may not be tainted, but the data they contain are. You cannot know this without inspecting each individual piece of data (the array below has two pieces of tainted data):
irb> y = [n, z, b] => ["More text. This is an example text file.\n", 40, "This is an example text file.\n"] irb> y.tainted? => false
You can also force data to be considered untainted by using the untainted method. And likewise you can force data to be tainted by using the tainted method.
irb> safe = n.untaint => "This is an example text file.\n More text." irb> safe.tainted? => false
$SAFE (Safe Levels)
Another feature in Ruby are Safe Levels. This is represented by a special variable $SAFE. The default in Ruby is 0, which really provides no safety. You can increase the $SAFE level in your program by setting the value of $SAFE to be higher, but once you do so you cannot lower it (this is for security purposes). Below is a brief description of the different safety levels.
- 0 – No restrictions. (This is the default value.)
- 1 – Potentially unsafe methods can not use tainted data. Current directory is not added to Ruby’s search path for loading libs.
- 2 – Ruby will not load any external files from globally writeable locations on the filesystem. File#chmod, Kernel#fork, and Process::setpriority methods are also disabled. All restrictions from 1 included.
- 3 – Any newly created objects, even those from within the program, are considered tainted automatically. You also cannot untaint objects. All restrictions for 1 and 2 included.
- 4 – Non-tainted objects created prior to the safe level being set cannot be modified. All restrictions from 1, 2 and 3 included.
