Unfortunately, they’re both wrong. quotemeta is not a shell-quoting function, so the escaping agrees largely, but not entirely, which means the code is still unsafe. The second example, as you noted, will get newlines wrong. The first one gets lots of things wrong:
$ echo '{}'
{}
$ echo "\{\}"
\{\}
$ echo "\\\\{\\\\}"
\{\}
$ echo "\\\\\{\\\\\}"
\\{\\}
With a bit of effort, you can use the discrepance in the last two demonstrations to cancel backslashes added by quotemeta. It’s tricky to exploit such an over-escaping vulnerability, but it’s entirely doable. In contradistinction, quoting shell strings by protecting single quotes and then single-quoting the entire string is absolutely airtight.
The PHP folks had to learn the same lesson when it came to using addslashes to quote strings interpolated into SQL. Since none of the databases use the exact same quoting rules as PHP, SQL injection is still possible when quoting is done that way. It takes effort to exploit the weakness, but attackers will go to that length; so now PHP has a bunch of database-specific quoting functions.
Makeshifts last the longest. |