I understand that you should NEVER trust user input from a form, mainly due to the chance of SQL injection.
However, does this also apply to a form where the only input is from a dropdown(s) (see below)?
I'm saving the $_POST['size']
to a Session which is then used throughout the site to query the various databases (with a mysqli
Select query) and any SQL injection would definitely harm (possibly drop) them.
There is no area for typed user input to query the databases, only dropdown(s).
<form action="welcome.php" method="post">
<select name="size">
<option value="All">Select Size</option>
<option value="Large">Large</option>
<option value="Medium">Medium</option>
<option value="Small">Small</option>
</select>
<input type="submit">
</form>
Whatever is submitted from your form comes to your server as text across the wires. There is nothing stopping anyone from creating a bot to mimic the client or type it in from a terminal if they wanted to. Never assume that because you programmed the client it will act like you think it will. This is really easy to spoof.
Example of what can and will happen when you trust the client.
Yes you need to protect against this.
Let me show you why, using Firefox's developer console:
If you don't cleanse this data, your database will be destroyed. (This might not be a totally valid SQL statement, but I hope I've gotten my point across.)
Just because you've limited what options are available in your dropdown does not mean you've limited the data I can send your server.
If you tried to restrict this further using behaviour on your page, my options include disabling that behaviour, or just writing a custom HTTP request to your server which imitates this form submission anyway. There's a tool called curl used for exactly that, and I think the command to submit this SQL injection anyway would look something like this:
(This might not be a totally valid curl command, but again, I hope I've gotten my point across.)
So, I'll reiterate:
NEVER trust user input. ALWAYS protect yourself.
Don't assume any user input is ever safe. It's potentially unsafe even if it arrives through some means other than a form. None of it is ever trustworthy enough to forgo protecting yourself from SQL injection.
Yes.
Anyone can spoof anything for the values that actually get sent --
SO, for validating dropdown menus, you can just check to make sure that the value that you're working with was in the dropdown - something like this would be the best(most sanely paranoid) way:
You could do something as simple as the following example to make sure the posted size is what you expect.
Then use mysqli_* if you are using a version of php >= 5.3.0 which you should be, to save your result. If used correctly this will help with sql injection.
As this question was tagged with sql-injection, here is an answer regarding this particular kind of attack:
As you've been told in the comments, you have to use prepared statements for the every single query involving any variable data, with no exceptions.
Regardless of any HTML stuff!
It is essential to understand that SQL queries have to be formatted properly regardless of any external factors, be it HTML input or anything else.
Although you can use white-listing suggested in other answers for the input validation purpose, it shouldn't affect any SQL-related actions - they have to remain the same, no matter if you validated HTML input or not. It means you still have to use prepared statements when adding any variables into the query.
Here you may find a thorough explanation, why prepared statements is a must and how to properly use them and where they aren't applicable and what to do in such case: The Hitchhiker's Guide to SQL Injection protection
Also, this question was tagged with mysqli. Mostly by accident, I presume, but anyway, I have to warn you that raw mysqli is not an adequate substitution for the old mysq_* functions. Simply because if used in the old style, it will add no security at all. While it's support for the prepared statements is painful and troublesome, to the point that average PHP user is just unable to endeavor them at all. Thus, if no ORM or some sort of abstraction library is option, then PDO is your only choice.
It's best to use a parameterized query in order to ensure against SQL injection. In that case the look of the query would be this:
When you supply a query like the above with text that is unverified for integrity (the input isn't validated on the server) and it contains SQL injection code it will be handled correctly. In other words, the request will result in something like this happening in the database layer:
This will simply select 0 results as it returns which will make the query ineffective in actually causing harm to the database without the need for a whitelist, a verification check or other techniques. Please note that a responsible programmer will do security in layers, and will often validate in addition to parameterizing queries. However, there is very little cause to not parameterize your queries from a performance perspective and the security added by this practice is a good reason to familiarize yourself with parameterized queries.