faceymcface faceymcface - 19 days ago 5
PHP Question

Potential dangers of using unprepared SQL queries when not processing user input?

Everyone knows or should know parameterized queries help to protect against SQL injection. All of the tutorials and documentation I have seen have revolved around using prepared SQL queries to process form input. But what about when there isn't any form input? I.e. a subsequent query after a user has been logged in such as

$stmt = "SELECT theme_preference FROM users WHERE user_id = '1234'";
$query = mysqli_query($conn, $stmt);


Is there any possible way an attacker could exploit this? (Let's say I'm using PHP).

Answer

The question is not whether the source of the data written in a SQL query is a http form. It's not even if it's from the current request.

The question is whether you trust the source of the data. And that may be a complex question.

You obviously do not trust something that comes from the current request. You also don't trust something that may have come from an earlier request, like for examples fields in a database that are modified by request data. But you also may or may not trust other fields in your database. For example you have IT ops staff, or DB admins. Do you trust them to not inject some kind of an XSS or secondary SQLi attack into a database field to steal user credit card data, which is stored in an audited table, so they cannot just go in and dump it without being noticed? If they injected javascript or a clever SQLi in the right place in a table that is not audited, they may steal credit card info by exploiting the vulnerable application, then change it back and remove all traces.

Also an application may have different sources for data, other systems may for example upload files (say XML) on APIs, data from those will be processed, some of it will eventually make it to the UI or used in SQL queries. If you trust those sources, you may choose to not implement protection against SQLi or XSS. But why would you, when it is easy? Multiple layers of defenses is always better than walking on thin ice.

So in short, the question is trust. If you absolutely trust the source of the data (like for example because it's static, hard-coded, or for some other reason), that's fine to use it directly in queries. But in case of SQL injection, using it properly (ie. in parameters) is so easy that you should just do that.

Also consider future changes. You are writing it in a SQL string without parameters because you know that it's safe now. Months pass, somebody adds a new feature, modifies your query, adds a few more parameters, one is from the request. But the pattern was already there, he will probably just copy-paste and go with the pattern - and your application is vulnerable.

My final point is static security scanners, those that look at your source code. Pretty much all of those will flag your code for SQLi if a variable is included in the query string itself without using parameters. That may of course be a false positive, but I doubt you want to bother with those findings, when you can avoid them in the first place.

So sometimes it's not just about the technical exploitability, there are other aspects too.