Issue #7791 has been updated by Student (Nathan Zook).


I can't claim to know much about ruby's internals, but this strikes me as the wrong approach.

Symbols have a number of features which differentiate them from other objects--strings in particular.  These features play important/central roles in MRI, are the basis of a significant performance improvements, and are relied upon throughout the code.

And substantial change to the behaviour of symbols would require complete audits at multiple levels.

It may be even worse in userland.  These same properties are exploited by programmers in the same ways.  Architectural decisions will need to be audited, and may need to be rethought.

Furthermore, the use of intern verses to_sym is arbitrary and incomplete.  There are many good reasons to dynamically generate methods, and in at least some of these cases, it would be desirable to generate the name of the method outside of the method declaration itself.  On the other hand, string-to-symbol conversions might well be done inside an eval.

---

One option that would me seem to be more feasible would be to create a class GCSymbol < Symbol.  GCSymbol use might initially be significantly restrained, and eased as the core team gained confidence in the idea.  I still don't like this.

---

The problem is that the utility of symbols is high enough that programmers very much want to take advantage of them.  The fact that a DOS exploit becomes available in certain use cases is the problem, and ought to be directly addressed.  Two options come to mind.  1) Define Symbol.defined?  In current code, it would look like this:

class Symbol
  def self.defined?(string)
    all_symbols.any?{|sym| sym.to_s == string}
  end
end

2) Define #to_existing_sym in the appropriate places.  This would raise an argument error if a proposed symbol was not already defined.

Either of these would provide the necessary facilities for HashWithIndifferentAccess, YAML, or similar constructs to proceed in safety, should they choose to do so, and neither requires tearing out & redoing a fundamental part of ruby.




----------------------------------------
Feature #7791: Let symbols be garbage collected
https://bugs.ruby-lang.org/issues/7791#change-35963

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Lots of Denial-of-Service security vulnerabilities exploited in Ruby programs rely on symbols not being collected by garbage collector.

Ideally I'd prefer symbols and strings to behave exactly the same being just alternate ways of writing strings but I'll let this to another ticket.

This one simply asks for symbols to be allowed to be garbage collected when low on memory. Maybe one could set up some up-limit memory constraints dedicated to storing symbols. That way, the most accessed symbols would remain in that memory region and the least used ones would be reclaimed when the memory for symbols is over and a new symbol is created.

Or you could just allow symbols to be garbage collected any time. Any reasons why this would be a bad idea? Any performance benchmark demonstrating how using symbols instead of strings would make a real-world software perform much better?

Currently I only see symbols slowing down processing because people don't want to worry about it and will often use something like ActiveSupport Hash#with_indifferent_access or some other method to convert a string to symbol or vice versa...


-- 
http://bugs.ruby-lang.org/