When is the correct time to use mysql_real_escape_string?
Should I be using it when I use isset(mysql_escape_string($_GET['param'])),
Should I be using it when I use $foo = mysql_real_escape_string($_GET['bar']);
Thanks
You need to call this function when building SQL queries with string literals.
You should not call it anywhere else.
The point of calling this function is to prevent you from executing SQL like SELECT * FROM Students WHERE Name = 'Robert'); DROP TABLE Students;--'.
mysql_real_escape_string will escape the ' character so that the evil string is treated entirely as a string.
You should use it whenever you don't trust the data you are inserting in a mysql query to prevent sql injections. For example all user forms data.
In your first example: no.
Second example: yes, if you are going to use the $foo variable in a query.
You should use it whenever you are inserting data into a database query (POST/GET data), but not if you just need to check the data.
You use mysql_real_escape_string whenever you have input from a user that you want to use in a query.
Here's how to use it:
$user = mysql_real_escape_string('$_GET['user']);
$password = MD5($user.$_GET['password']);
$query = "SELECT * FROM users WHERE user = '$user' AND password = '$password' ";
//the quotes are vital !! ^ ^ or you will not be safe!
Here's example code that doesn't work:
Broken code
$user = mysql_real_escape_string('$_GET['user']);
$password = MD5($user.$_GET['password']);
$query = "SELECT * FROM users WHERE user = $user AND password = '$password' ";
In the example I can login into your system by entering any password whatsoever and
user or (1=1) --. This will make the query to read:
SELECT * FROM users WHERE user = user or (1=1) -- AND password = '$password
And will approve all logins because the password never gets checked.
When using mysql_query, you can only ever execute one SQL-statement at a time, so:
$query = "SELECT * FROM a; DELETE FROM a WHERE (1=1)"
mysql_query($query);
Will result in an error, because cannot be a part after the ;.
This code however will work:
Danger
$query = "SELECT * FROM a; DELETE FROM a WHERE (1=1)"
mysqli_query($query);
Because the improved mysqli_query does allow two or more statements to be executed in one go.
Related
This question already has answers here:
How to insert values in a PHP array to a MySQL table?
(2 answers)
Closed 5 years ago.
I'm using PHP session variable to track character ID's between two tables, characters and character_data_store.
The session ID definitely has the correct ID as I have had to print its value before it goes into the mySQL query.
For testing I selected a user I knew had a rapsheet and used
$usersql = "SELECT *
FROM character_data_store
WHERE character_data_store.`key` = 'RapSheet'
AND character_data_store.character_id = '216'";
Obviously I can't use this for all users as I need to confirm the right one has been selected so thats where the session variable comes in.
I've tried using:
$correctPlayer = $_SESSION['selpid'];
echo $correctPlayer; #confirm it's the right id and then remove
$usersql = "SELECT *
FROM character_data_store
WHERE character_data_store.'key' = 'RapSheet'
AND character_data_store.character_id = '$correctPlayer'";
I did some searching on SO and I found that int's need to have double quotes around them not single quotes, I tried that and had no luck but someone else suggested putting the session ID in exactly which I tried next:
$usersql = "SELECT *
FROM character_data_store
WHERE character_data_store.'key' = 'RapSheet'
AND character_data_store.character_id = {$_SESSION['selpid']}";
Each time I do this I get mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given which SO tells me is because this operation results to false, I assume because it's not accepting the playerID from selpid or $correctPlayer?
It definitely works with the testing user where the playerID is inserted directly into the query. But I can't think of a way to do that since I need to match the playerID from table "characters" where the search is done against their first and last name and then pull the rapsheet data against the same playerID in table "character_data_store".
How do I use a variable in the WHERE condition of a MySQL query using a php variable?
You have obvious error in your code. You are missing quotes in {$_SESSION['selpid']} and you are using quotes in column name. Your query should be
$usersql = "SELECT * FROM character_data_store WHERE character_data_store.`key` = 'RapSheet' AND character_data_store.character_id = '{$_SESSION['selpid']}'";
You should not use quotes in column name, instead use backquotes(`) if you really need. I recommend prepared statements.
There are multiple ways to do this. A naive way to do this would be-
$usersql = "SELECT * FROM character_data_store WHERE character_data_store.'key' = 'RapSheet' AND character_data_store.character_id = ".$correctPlayer;
But to avoid sql injections I would recommend you use bindparam function to bind paramaters in a statement.
$sql="SELECT * FROM character_data_store WHERE character_data_store.'key' = 'RapSheet' AND character_data_store.character_id = ?";
if($stmt = $dbh->prepare($sql)){
$stmt->bindParam(1, $correctPlayer, PDO::PARAM_STR);
$ql = $stmt->execute() or die("ERROR: " . implode(":", $dbh->errorInfo()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$result['data'] = $row;
currently I've been using this:
SELECT * FROM `meow` WHERE profile LIKE '%$username%'
But the problem I'm facing is if someone puts the letters 'a' it will pull everything that contains a and that's a bit of a security risk on my end, How do i search just 1 column to see if it matches $username exactly? not the whole table?
For exact string matching you should the = operator instead of the like operator:
SELECT * FROM `meow` WHERE profile = '$username'
Stop using string concatenation to build your query. It's evil. Instead use mysqli or pdo and use prepared statements.
$pdo = new PDO('mysql:host=localhost;dbname=yourdb', 'your_username', 'your_password');
$stmt = $pdo->prepare("SELECT * FROM `meow` WHERE profile = ?");
$stmt->execute(array($username));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Also, use equality, instead of like, if you wish to check for exact matches.
Instead of using like use equal to
try this :
SELECT * FROM meow WHERE profile = '$username'
Try with -
"SELECT * FROM `meow` WHERE profile LIKE '$username'"
for exact match.
For a particular process I am storing a list of mysql queries in Database using php variables for condition data retrieval.
I'm storing:
Select count(1) from Users where user='$user1'
I have written a script where I first initialize: $user1="XYZ";
Then I select the above query from database and try to execute it again using mysql_query.
But the value of $user1 is not getting initialized as required.
Please fidn below the psuedo code:
$user1="xyz";
//selecting the query
$select_table="SELECT * FROM `test`";
$result_table=mysql_query($select_table);
$select_query=mysql_result($result_table,$j,"Select_Query");
$panelinttable_result=mysql_query($select_query);
This will not work as when you retrieve data, $user1 will not be a variable but a part of string "Select count(1) from Users where user='$user1'".
Using str_replace() should work :
$select_query = mysql_result($result_table,$j,"Select_Query");
$select_query = str_replace('$user1', $user1, $select_query);
$panelinttable_result=mysql_query($select_query);
Also, why are you storing those queries in database ?
It would be better to make functions for this.
function userExists($user) {
$query = mysql_query("Select count(1) from Users where user = '".$user."'");
return mysql_num_rows($query);
}
Alt A below is a statement from a php-mysql tutorial. It works as it should.
I found the id-value rather obfuscated and tested alt B. This also worked!
What is the point with the id-value of alt A?
MySQL 5.0.51, PHP 5.2.6
// Alt A :
$sql = "SELECT * FROM example WHERE id = '".$q."'";
// Alt B :
$sql = "SELECT * FROM example WHERE id = $q";
This are just two different approaches to building a string from static and variable data.
Alternative A uses concatenation, or the joining of string and variable tokens using the concatenation operator.
Alternative B uses variable expansion, wherein the variables inside a double-quote-delimited string are expanded to their values at evaluation time.
Neither is necessarily better or preferred, but if you have to have single-quote-delimited strings, for example, then you would need to use alternative A.
Of course, neither of these is preferable to building SQL queries with bound parameters, as not doing so leaves you vulnerable to SQL injection attacks.
Theres two reasons to use the example in 'Alt A'. First is if the string is enclosed in single quotes '', the variable's name will be used in the string instead of it's value.
$id = 7;
'SELECT * FROM table WHERE id = $id' //works out to: WHERE id = $id
"SELECT * FROM table WHERE id = $id" //works out to: WHERE id = 7
Secondly, it's useful to combine strings with the results of a function call.
"SELECT * FROM table WHERE id = '".getPrimaryId()."'"
Outside of what has already been said I've found it best practice, if I'm writing a query, to write it as so:
$sql = "SELECT * FROM table WHERE uid=" . $uid . " LIMIT 1";
The reason for writing SQL like this is that 1. MySQL query doesn't have to parse the PHP variables in the Query and 2 you now easily read and manage the query.
When PHP communicates with MySQL, it is actually (in essence) two languages communicating with each other. This means that a string will be processed by the first language before being sent to the other. It also means that it is important to think in terms of the receiving language
In this case:
$q = 'some_name';<br/>
$query = "SELECT * FROM exempel WHERE id = $q";<br/>
you are telling MySQL to
"SELECT * FROM example1 WHERE id = some_name.
In this case:
$q = 'some_name';<br/>
$query = "SELECT * FROM exempel WHERE id = '$q'";<br/>
and this case:
$q = 'some_name';<br/>
$query = "SELECT * FROM exempel WHERE id = '".$q."'";<br/>
you are telling MySQL to
"SELECT * FROM example1 WHERE id = 'some_name'.
The first example should cause an error as some_name is not a valid part of a MySQL query (in that context). On the other hand, the next two will work fine, because MySQL will look for the String "some_name".
You can also do this:
$sql="SELECT * FROM exempel WHERE id = {$q}";
which is useful for setting off things like:
$sql="SELECT * FROM exempel WHERE id = {$row[id]}";
in 'alt B', $q must be an int or float or other numeric
in 'alt A', $q can be anything a string, int, etc.
The single quote makes that possible. It's just hard to see sometimes if you are looking at it for the first time.
$befal = mysql_query("SELECT * FROM users WHERE username = $_GET[username]");
$rad = mysql_fetch_assoc($befal);
Equals
Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in C:\profile.php on line 4
I have a user called Admin in the field username and it still dont work. profile.php?user=Admin...
This works if I use the ID though:
$befal = mysql_query("SELECT * FROM users WHERE user_id = $_GET[id]");
$rad = mysql_fetch_assoc($befal);
What can be the problem?
Thanks
Errr... that's a recipe for getting hacked. I would like to introduce you to SQL injection as characterized by this very funny yet poignant cartoon.
Try this instead.
$username = mysql_escape_string($_GET['username']);
$query = mysql_query("SELECT * FROM users WHERE username = '$username'");
Try it like this:
$befal = mysql_query("SELECT * FROM users WHERE username = '$_GET[username]'");
You have to encapsulate a string parameter in apostrophes.
[UPDATE]
Just like cletus and Olaf pointed out, with the above sql statement you are very prone to SQL Injection. Check out their posted answers to see what I mean.
Now that you've got your answer, try entering
Something' OR '1' = '1
as username - you've managed to produce a nice SQL-injectable application.