There are quite a lot of various "Is X sufficient to prevent SQL injection?" questions, but I haven't been able to find one that explains this specific thing very well.
Since I can't bind values for column names in prepared statements, there has to be some other safe way to accept user input for ordering queries and other types of things where prepared statements won't help. If I have a $sort_column
that I've pulled out of $_GET
, I obviously shouldn't just use it directly in the query.
$no = "SELECT col1, col2, col3 FROM table ORDER BY $sort_column;";
Rather than just escaping $sort_column
and trying to run the query, it seems like I could check it against a list of legitimate column names for the table in question beforehand. This would let me tell the user they had selected an invalid column without needing to figure it out from a database error. From what I've read, even if I do this, using $sort_column
without escaping it is still unsafe, but I don't understand how, unless in_array
doesn't work like I think it does.
$good_columns = array("col1", "col2", "col3");
if (in_array($sort_column, $good_columns, true)) {
$sql = "SELECT col1, col2, col3 FROM table ORDER BY $sort_column;";
And what if I use the column name from my "safe" array rather than using the user supplied value at all?
function is_column($column, $good_columns) {
$key = array_search($column, $good_columns);
if ($key !== false) {
return $good_columns[$key];
}
return false;
}
$good_columns = array('col1', 'col2', 'col3');
$my_column = is_column($sort_column, $good_columns);
if ($my_column) {
$sql = "SELECT col1, col2 FROM tbl1 ORDER BY $my_column;";
I do escape everything, I'm not trying to avoid doing it or advocate not doing it. I'm just curious how something like this would still be vulnerable.