Symbols in Ruby are atoms (the term "atom" spans languages), and GC/space issues plague any persistent term like an atom, in any language.
And thus I arrive at a key question: Does Ruby have something like `list_to_existing_atom', or some mechanism for telling if a symbol exists already? I see no analog to this, only the `ID2SYM' macro in the extensions API, and similar calls like String#to_sym.
Perhaps there is some way to clean up symbols after they are created. This to me would seem like the ideal route. It's good they've got a stop-gap fix by changing defaults, but it feels to me like they're punting here. Perhaps users who do [ab]use this feature also would not like DOS attacks?
I hope others who know more about Ruby extension development, and symbol management capabilities, can chime in on these questions.
however, on ruby trunk they added a method: rb_check_id which can be used to check if a string has been already symbolized (https://github.com/ruby/ruby/blob/trunk/parse.y#L10465). this means when these reflection methods get passed a string and it hasn't been symbolized they can bail out and not symbolize the string. (https://github.com/ruby/ruby/blob/trunk/object.c#L2073)
Indeed, when researching just now, I saw examples of people throwing strings at Module#const_defined?, which no doubt get converted to symbols straightaway.
So if you reference the symbol :foo, it will transparently get pinned in memory somewhere. Referencing :foo again will not allocate an additional object - the interpreter will just give you the existing symbol.
This is usually not an issue, because an application typically operates on a small, fixed set of known symbols. But if an attacker can generate arbitrary symbols (e.g. if you call .to_sym on user input), he can exhaust memory.
"Since Ruby symbols are not garbage collected, this can result in a denial of service attack."
If you have a long running Ruby app,and it does not garbage collect symbols, then those symbols are... constants I guess?That survive till the app stops operating? So I guess the assumption is that no app should use too many symbols (and they don't use much memory anyway?)