I prefer to have a storage format that by definition can not contain executable code instead of relying on a filter that tries to prevent malicious code execution inside a string eval. One bug in Safe and the "SafestUndumper" is no longer save, but instead happily executes malicious code.
Also, the "non-executable" formats force the programmer to use a parser. There is no way to accidentally or intentionally use a string eval on those formats.
So, who would intentionally use a string eval on untrusted code?
- The new programmer who does not know enough about the project.
- The new programmer who did not learn the style guide by heart.
- The lazy programmer who thinks "It's just a quick hack, I'll use string eval for now because I trust my current, hand-written config file, and fix that problem later." (We all know from experience that it won't be fixed until at least a few years later.)
- The stupid programmer who thinks "all of that stinking modules are just a stupid waste of time, eval is much faster".
A little bit of bean counting:
Actually, every storage format that can contain strings can - in theory - also contain executable Perl code. But when reading back formats like XML or JSON, an explicit string eval on an extracted string is required, and that string eval is not present in the library reading the file format (or, at least, it should not be present).
Oh, and string eval means more than just eval $string:
- do $filename is a string eval on a file content - exactly what the four programmers from above would like to use to undump Data::Dumper output.
- require $filename - it's do $filename at the core, plus a little bit of book keeping to avoid repeated reading of the file.
- use $filename - require with an implicit BEGIN block.
- evalbytes $bytes - new since v5.16
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)