Project

General

Profile

Bug #11442

Bug: Symbols should be taintable.

Added by gwelch (Grant Welch) about 4 years ago. Updated 11 days ago.

Status:
Closed
Priority:
Normal
Target version:
-
ruby -v:
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
[ruby-core:<unknown>]

Description

Subject: String#to_sym returns an untainted Symbol.

Taint checking can be subverted by a String if a tainted String is converted to a Symbol. After experiencing this issue, I went looking for unit tests in ruby/ruby, ruby/mspec, and ruby/rubyspec, but was unable to come up with any tests that focus on $SAFE. If they exist, could you point out where they are located? If not, I'd be willing to write some.


Proof of Concept:

# cat untainted_sym.rb

#!/usr/bin/env ruby -w
print 'Enter a string? '
a = gets
puts "a: #{a.inspect}, tainted? #{a.tainted?}"
b = a.to_sym
puts "b: #{b.inspect}, tainted? #{b.tainted?}"
c = b.to_s
puts "c: #{c.inspect}, tainted? #{c.tainted?}"
puts "a == c: #{a == c}"

Output:

$ ruby -w untainted_sym.rb
Enter a string? foobar
a: "foobar\n", tainted? true
b: :"foobar\n", tainted? false
c: "foobar\n", tainted? false
a == c: true

Sample Workaround: (to provide the expected SecurityError)

# safe_level, 1 or 2
# uncertain_var, some variable that could, potentially, be tainted
untainted_sym = proc { $SAFE=safe_level; eval("'#{uncertain_var}'") && uncertain_var.to_sym}.call   # => Symbol for untainted var, SecurityError for tainted var

Versions Tested:

  • ruby 1.9.3p551 (2014-11-13 revision 48407) [x86_64-linux]
  • ruby 2.0.0p645 (2015-04-13 revision 50299) [x86_64-linux]
  • ruby 2.1.6p336 (2015-04-13 revision 50298) [x86_64-linux]
  • ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]

History

#1

Updated by gwelch (Grant Welch) about 4 years ago

  • Description updated (diff)
#2

Updated by gwelch (Grant Welch) about 4 years ago

  • Description updated (diff)
#3

Updated by gwelch (Grant Welch) about 4 years ago

  • Subject changed from String#to_sym returns an untainted Symbol. to Bug: Symbols should be taintable.

After some additional testing, I've come to the conclusion that Symbols cannot be tainted (example below). I expect this may be due to the fact that symbols have a dual meaning. 1) They are a String because we want them to be human-readable, and 2) they are a Number so they can be quickly retrieved. It's understandable that Numbers don't carry a taint flag, but since Symbols have practical use cases in place of Strings, they should carry over 'tainted?' when coming from String#to_sym.

proc {$SAFE=3;(a = :foo).tainted?}.call # => false
a = :foo
a.taint
a.tainted? # => false

Note: I have come to the conclusion that the behavior is as expected, but I am leaving the issue as a Bug (rather than a Feature) because the logic that Symbols should be un-taintable is flawed.

Updated by jeremyevans0 (Jeremy Evans) 11 days ago

  • Status changed from Open to Closed

Ruby makes taint and untaint just return the receiver if called on any object that is not considered taintable. That includes all immediate objects (symbols, integers(fixnums), true, false, nil), as well as integers(bignums) and floats. So this behavior is expected and not a bug.

Also available in: Atom PDF