Prepared statements resist SQL injection, but are not immune to injection, and I always break out in hives when people describe their complete SQL injection security strategy as “we use prepared statements”.
There are roughly two kinds of SQL injection that are possible when prepared statements are used in a PHP application.
Neither are relevant to our codebase.
If there’s a third that I’m not aware of, I promise you most PHP developers aren’t either, and should be made aware.
This depends on your database, doesn’t it? There are versions of MySQL where you can’t even parameterize a LIMIT. There are databases that can’t parameterize column names for search queries with selectable columns. It can be hard to build IN queries. There are lots of little exceptions.
It’s the confidence that “parameterized queries means no SQL injection” that scares me. We still find SQLI in applications despite the fact that most teams now pretty reliably parameterize queries.
Allowing end users to supply column names implicitly invites injection, and a strict whitelist is the sane solution here. The linked post in that section explains the caveats in detail.
It sounds to me like “we aren’t actually using prepared statements for this query” is the culprit, however.
[Comment removed by author]
In PHP’s PDO case, there’s only a corner case with emulated prepared statements that I’m aware of.