Considering a project where will work more than one developer and that will receive constant update and maintenance, what of the two codes below can be considered the best practice in PHP, considering Readability and Security? If we talk in performace, the second option will probably be a little better, but there are ways to solve this point.
Option 1
$user = $_POST['user'];
$pass = $_POST['pass'];
// Prevent SQL Injection and XSS
$user = anti_injection($user);
$pass = anti_injection($pass);
if(strlen($user) <= 8 && strlen($pass) <= 12)
{
// SQL query
$sql = "SELECT id
FROM users
WHERE username = '$user' AND password = '$pass';";
}
Option 2
// Retrieve POST variables and prevent SQL Injection and XSS
$_POST['user'] = anti_injection($_POST['user']);
$_POST['pass'] = anti_injection($_POST['pass']);
if(strlen($_POST['user']) <= 8 && strlen($_POST['pass']) <= 12)
{
// SQL query
$sql = "SELECT id
FROM users
WHERE username = '" . $_POST['user']. "' AND password = '" . $_POST['pass'] . "';";
}
EDIT 1
I am not using MySQL, my database is PostgreSQL
Don’t do either.
I can only assume
anti_injectionis some sort of custom filtering function, which is a Bad Idea™. If you really want to adopt either of these idea, you should be usingmysql_real_escape_string.The only way to remain secure when writing SQL queries is to use parameters, e.g. through MySQLi. The
mysql_*functions are becoming deprecated anyway, so you’re best to move across as soon as possible.In fact
mysql_real_escape_stringis not a foolproof defense against injection attacks. Consider an integer comparison in a query, such asWHERE $var > 30. I could inject1=1 or 100into$varsuccessfully, and completely break the logic.Parameters completely separate data from query language, completely mitigating the injection risk. The server receives a query containing parameter notation, and a set of values to insert, so it can handle the query language and data completely differently.
Furthermore, you seem to be storing passwords in plaintext. This is a bad idea. You should look into a strong password storage hash algorithm such as bcrypt, which makes it very difficult to obtain plaintext passwords from the hashes.
MD5 and SHA1 are not ideal for password storage, because they are designed to be fast, meaning an attacker can quickly crack even strong salted passwords. Modern GPUs can achieve 5 billion MD5 hashes per second. In fact, there are people with dedicated hash cracking rigs, some of which can crack MD5 at 45 billion hashes per second.
You should also take a look at these awesome questions, which completely cover SQL injection attacks, password storage, and a multitude of other security issues:
Update: You mentioned you’re using postgres. You can use PDO to run parameterised queries from PHP, as described briefly here.