This question has been asked many many times before.
It's always best to use PDO, but if you have to use the mysql_* lib, do it like this:
Escaping for parameters
The following code is 100% secure:
$var = mysql_real_escape_string($_POST['var']);
$query = "SELECT * FROM table1 WHERE afield = '$var' "
// You must quote your $vars ^ ^
// failure to do so defeats the escaping and causes syntax errors.
No further action is needed to make the code SQL-injection same.
Escaping for dynamic column/table names
This code:
Unsafe, does not work
$afield = mysql_real_escape_string('$_POST['var']);
$query = "SELECT * FROM table1 WHERE `$afield` = 1 "
//You can only use escaping for values, never for dynamic SQL.
This will not work, you need to check database, table and column names against a whitelist.
100% Safe for dynamic SQL
$allowed_fields = array('field1', 'field2');
$afield = $_POST['afield'];
if (in_array($afield, $allowed_fields)) {
$query = "SELECT * FROM table1 WHERE `$afield` = 1";
}
About hashing and salting
You only use salted hashes for passwords.
It is a bad idea to store unencrypted passwords in a database, instead you store a hashed password.
In order to defeat rainbow tables you have to salt the hash with a different semi-random salt; the salt does not need to be secret, it just needs to be somewhat random.
//To add a user.
INSERT INTO users (name, salt, passhash)
VALUES ('$username', '$salt', SHA2(CONCAT('$salt','$password'),512));
//To check a password:
SELECT u.id FROM users u
WHERE u.name = '$username'
AND passhash = SHA2(CONCAT(salt, '$password'),512);
//To change a password:
UPDATE users u SET passhash = SHA2(CONCAT(s.salt, '$newpassword'),512)
WHERE u.id = (SELECT u2.id FROM (
SELECT u1.id FROM users u1
WHERE u1.name = '$username'
AND passhash = SHA2(CONCAT(u1.salt, '$oldpassword'),512) u2) s
See also:
How to prevent SQL injection with dynamic tablenames?
How does the SQL injection from the "Bobby Tables" XKCD comic work?
How can I prevent SQL injection in PHP?