Tainted - Ruby security

Ruby has implemented a multi-level security concept ever since. It is for controling security-relevant tasks and how a Ruby script executes them.

Security-relevant operations

Dangerous operations from the Ruby perspective are accesses to environment variables, the file system or command line interpreters. That means entities defined outside of Ruby itself.
Everything that comes from these sources is insecure (or tainted):

File.read('README.md').tainted? # => true
ENV['LANG'].tainted? # => true

Objects generated internally are not:

'Ruby'.tainted? # => false
Fixnum.tainted? # => false

The tainted flag is defined on each and every object. Which operation is executeable for tainted objects depends on the SAFE level.
The tainted property is passed, like:

home = ENV['HOME']
home.tainted? # => true
user = home.split('/')[-1]
user.tainted? # => true

Ruby SAFE levels

Since version 2.3.0, Ruby scripts can be executed in two different SAFE levels (0 and 1). The levels 2 - 4 are no longer supported:

$SAFE = 3 # => $SAFE=2 to 4 are obsolete (ArgumentError)

The level 0 is set by default:

$SAFE # => 0

The SAFE Level can only be increased, but never be decreased:

$SAFE # => 0
$SAFE = 1
$SAFE # => 1
$SAFE = 0 # => SecurityError: tried to downgrade safe level from 1 to 0

Ruby - Tainted Love

It is briefly demonstrated, what happens, if a tainted object executes an operation, that is not allowed in its SAFE level.

# operation.txt
puts 'Dangerous operation.'

The text file is read:

operation = File.read('operation.txt')

This string can be evaluated with SAFE level 0, but not with SAFE level 1:

$SAFE # => 0
eval(operation) # => "Dangerous operation."
$SAFE = 1
eval(operation) # => SecurityError: Insecure operation - eval

Tainting an object is like:

ruby = 'Ruby'
ruby.tainted? # => false
ruby.tainted? # => true

And un-tainting it:

ruby.tainted? # => false

However, it should also be clear whether the external source can be trusted or not.
Consequently classes also can be tainted, but this does not include tainting the class instances automatically:

String.tainted? # => false
String.tainted? # => true
String.new.tainted? # => false

Other Ruby implementations such as JRuby do not implement SAFE levels. JRuby is based on the JVM security model.