SQL injection is just one case of the broader threat of code injection. That is, any case where user input (or any other untrusted content) is run as code.
This includes things like eval() but quite a few other vectors as well. The answer from @thebod includes a link to a great StackOverflow thread: Exploitable PHP functions.
Even SQL injection can't be solved 100% by parameters or escaping. Both of those techniques only help to sanitize individual values in SQL expressions. You might also need to allow user input to select tables, columns, SQL keywords, or whole expressions. For those, parameters and escaping don't help. Example:
$sql = "SELECT * FROM mytable ORDER BY $sortcolumn $asc_or_desc";
In that example, the column name to sort by and the direction (ASC
vs. DESC
) are based on variables. Were the variables set from trusted input, or were $_GET parameters used verbatim, resulting in a SQL injection vulnerability?
A better solution for those cases is allowlisting. That is, take the user input, compare it to a list of column names that are permitted for this dynamic query, and if the user input doesn't match one of those predefined choices, then either fail, or else use a default value.