Reputation: 2851
I know this question has been asked a million times, but what is the standard today (2013) for validating a query string before running a variable in an SQL statement?
For example, if I receive a variable "id" from the url via $_GET['id']:
$id = $_GET['id'];
...what should I do before running:
SELECT * FROM users WHERE id="$id"
is this enough:
$id = mysql_real_escape_string($_GET['id']);
... for this specific example?
Upvotes: 0
Views: 329
Reputation: 20997
You probably should switch to mysqli
from deprecated mysql_
where you can take advantage of mysql::prepare()
which allows you to use placeholders:
$stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?");
$stmt->bind_param("s", $city);
$stmt->execute();
Which are as safe as SQL can get.
But mysql_real_escape_string()
is enough to prevent SQL injection (as long as you enclose string in quotes).
Upvotes: 0
Reputation: 562290
The simplest validation in this case is just to coerce to integer.
<?php
$id = (int) $_GET['id'];
$sql = "SELECT * FROM users WHERE id=$id";
Then you don't need to put quotes around the variable in your SQL expression. In fact, there are cases where using quotes around a numeric literal messes up the SQL optimizer, so I am always puzzled why so many people get into this habit.
If you want to get into more sophisticated validation, read up on PHP's filter extension.
And finally, an even better (easier, faster, more secure) way to use variables in SQL is to use query parameters. However, PHP's deprecated mysql_*
functions don't support query parameters, so you should learn mysqli or PDO.
Upvotes: 1
Reputation: 7034
It's irrelevant, since id in the most of the conventional cases is an integer. You have to use:
$id = (int)$_GET['id'];
The standard way nowadays is using parametized queries/prepared statements which are represented in the libs of MySQLi and PDO.
For any manual validation, you need to consider wisely what you expect to recieve to this variable.
As in this case, you only expect integers, nothing else. You don't need people to send through ID -> 1 UNION SELECT ...
which is still a valid string, and mysql_real_escape_string won't do anything to it.
Upvotes: 1