For what it's worth, I am not attempting to compare Ruby (or generally dynamic languages) to C++. I am comparing Ruby to statically, strongly-typed languages. C++ is statically typed but is generally not a strongly-typed language, since there are many ways to escape strong typing, either willingly (e.g. with a cast to `void*`) or by accident (e.g. through UB).
> But "safety properties" includes a huge amount of stuff that isn't necessarily security relevant.
Good remark.
However, as a former safety (not security) researcher, it feels to me like the consensus in some parts of the security community is that once you have lost safety guarantees (i.e. you're not sure what your program is going to do), you have lost this entire line of defense and need to move to the next one (e.g. containerization).
Example: Python has a very clear syntax and it is often easy to audit code to find out whether the algorithm implemented matches the specifications. However, Python is also a language in which `True`, `False` or integer literals can be redefined dynamically. So, with this in mind, how can you be sure that your Python code that appears to calculate fibonacci is not going to actually `ctype` into something memory-unsafe that could be used to escape into the shell?
Of course, this example (and anything analogous in other dynamic languages) requires active malicious intent by the author of the code or one of the module it uses, but it's not too hard to come up with examples that end up with OS or XSS injections, without malicious intent by the code author.
I believe that we both agree that these examples are safety issues escalating into security issues.*