Every answer here covers only part of the problem.
In fact, there are four different query parts which we can add to itSQL dynamically: -
- a string
- a number
- an identifier
- a syntax keyword.
$orders = array("name", "price", "qty"); // Field names
$key = array_search($_GET['sort'], $orders)); // See if we have such a name
$orderby = $orders[$key]; // If not, first one will be set automatically. smart
$query enuf= :"SELECT * FROM `table` ORDER BY $orderby"; // Value is safe
To ease the process I wrote a whitelist helper function that does all the job in one line:
$orderby = white_list($_GET['orderby'], "name", ["name","price","qty"], "Invalid field name");
$query = "SELECT * FROM `table` ORDER BY $orderby";`$orderby`"; // Valuesound isand safe
However, thereThere is another way to secure identifiers - escaping but I rather stick to whitelisting as a more robust and explicit approach. AsYet as long as you have an identifier quoted, you can escape backticks inside by doubling them.
As a further step, we can borrow a truly brilliant idea of using some placeholder (a proxy to represent the actual value in the query) from the prepared statements and invent a placeholder of another type - an identifier placeholder.
So,quote character to make the long story short: it's a placeholderit safe. For example, notby default for mysql you have to prepared statement can be considered as a silver bulletdouble the quote character to escape it.
So, a general recommendation may For other other DBMS escaping rules would be phrased as
As long as you are adding dynamic parts to the query using placeholders (and these placeholders properly processed of course), you can be sure that your query is safedifferent.
So, a general recommendation may be phrased as
- Any variable that represents an SQL data literal, (or, to put it simply - an SQL string, or a number) must be added through a prepared statement. No Exceptions.
- Any other query part, such as an SQL keyword, a table or a field name, or an operator - must be filtered through a white list.
###Update
So, unlike whatever "escaping", prepared statements is the measure that indeed protects from SQL injection (when applicable).
If you're still not convinced, here are a step-by-step explanation I wrote, The Hitchhiker's Guide to SQL Injection prevention, where I explained all these matters in detail and even compiled a section entirely dedicated to bad practices and their disclosure.