This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 8 years ago.
Every question which I asked on stackoverflow I received a question that It was easy to do a php injection into my script.
I've now a example and checked some tutorials on youtube.
Am I doing this right now?
This is an example how I'm working now
if($user->isLoggedIn()) {
$pakuser = $user->data()->username;
$sql = $db->query("SELECT * FROM users
INNER JOIN post ON users.username = post.add
WHERE post.id = $id AND post.add = '$pakuser'")
or die(mysql_error());
if ($sql === FALSE) {
}
if($row = $sql->fetch_object())
if($row->add)
{
?>
<p>edit this post<br><br>BEWARE OF DELETING YOUR CONTENT THERE IS NO GO-BACK<BR>Delete this post </p>
<?php
}
}
Everytime the user can manipulate your sql-query without any restriction, there is a security-issue. Here is an example:
$query_string = "SELECT * FROM user WHERE (name='$username' AND password='$password')";
if the user sends a password like:
"something') OR ('1' = '1"
the query will change to:
$query_string = "SELECT * FROM user WHERE (name='Name' AND password='something') OR ('1' = '1')";
Because '1'='1' is always true, this will return each user in your database.
Instead you can change the example above to:
$query = mysqli->prepare('SELECT * FROM user WHERE (name=? AND password=?)');
$query->bind_param('ss', $username, $password);
$query->execute();
This will filter all strings that could break your sql-query.
It seems like you are still just passing variables straight through into the query. Yes, this may work, but is not necessary secure.
You could have a look at using PDO instead, which has means of being able to verify the data type that you are wanting to pass through into your query rather than just passing a variable into the query string.
In terms of using mysqli, have a look at mysqli_real_escape_string if you have not already. It is well documented.
Related
This question already has answers here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
How can I prevent SQL injection in PHP?
(27 answers)
Reference - What does this error mean in PHP?
(38 answers)
Closed 2 years ago.
I have been using the same code for years and all of a sudden I'm having problems that I cannot figure out. I am making a very simple query to MySQL in PHP using a variable in the statement. When I use the variable, it returns no results. When I manually type in the value of the variable instead, it works. I use this syntax all day long and never have had a problem. What on earth is wrong?
$name = "Fred";
$query = "SELECT * FROM database WHERE name='".$name."'";
$result = mysqli_query($connection, $query);
if (mysqli_num_rows($result) != 0) {
echo "Found record.";
}
If I replace the $name variable with Fred, it finds the record. If I echo the query with the variable before it executes and place that exact statement into MySQL directly in phpMyAdmin, I also get the result. If I leave the statement as-is with the variable in place, I get no result. Please help.
your query states SELECT * FROM database WHERE name='".$name."', this means that your table name is database, now i dont know how you actually created this table but database is a MYSQL reserved keyword change the name of your table to something else or just change your query to
$query = "SELECT * FROM `database` WHERE name='$name'";
assuming that your database connection is fine your code should now work
also worth noting, whenever acquiring data from a database use prepared statements instead of raw data as it makes you vulnerable to sql injection, in your case your code should be something like this
$name = "Fred";
$stmt = $dbconnection->prepare("SELECT * FROM table_name WHERE name=?")
$stmt->bind_param("s", $name);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows != 0)
{
echo "Found record.";
}
this is more secure
You shouldn't use mysqli excepted for old projects you can't upgrade, it's outdated and suffers from potential sql injection vulnerabilities.
Instead, I recommand you to learn PDO and prepared statements.
Your request should look like this :
$name = 'Fred';
$sql = "SELECT * FROM my_user_table WHERE name = :name";
// You should have set your pdo instance in a script handling your database connexion and reusing it in any script making requests.
$result = $pdo->prepare($sql);
// Here you dynamically inject values in your request and tells pdo what type of data you are expecting
$result->bindValue(':name', $name, PDO::PARAM_STR);
$result->execute();
if( $result->rowCount()) {
echo "{$result->rowCount()} result(s) found";
}
else {
echo 'No result found';
}
Here's the official doc :
https://www.php.net/manual/fr/book.pdo.php
This will also more than probably fix your problem.
This question already has answers here:
Can I mix MySQL APIs in PHP?
(4 answers)
Closed 3 years ago.
I've set a local server using PHPMyAdmin, and I'm presenting some dynamic data that is stored in that server using some PHP, HTML and SQL. The problem is that whenever I pass a variable that is stored using $variable = mysqli_real_escape_string($conn, $_GET["variable"]); and then I use that variable in a SQL query similar to this one $sql = 'SELECT * FROM assets WHERE variable="$variable";. The array that is generated is empty.
When I do a print_r($variable);, I get the variable that the code is expecting, so I'm not sure why the query sends an empty array. Then, when I hardcode the SQL query with the value of print_r($variable), the correct array is obtained from the query.
Code in PHP that is not working
$variable = mysqli_real_escape_string($conn, $_GET["variable"]);
print_r($_GET["location"]);
// make SQL
$sql = 'SELECT * FROM assets WHERE variable="$variable"';
Where $conn = mysql_connect('localhost', 'user', 'password', 'table');
The connection is correct though
then for example when I hardcode it using the result I get from
print_r($_GET["variable"]); prints N1 on the screen
This PHP is working, but it won't be dynamic
$sql = 'SELECT * FROM assets WHERE variable="N1';
I'm expecting to see all the results were the field variable = to a $_GET["variable"], where $_GET["variable"] is stored in $variable, but all I'm getting is an empty string.
You could use a prepared statement and binding param (for this you don't need the real string escape id done by the msqli prepared and binding)
$conn= new mysqli('localhost', 'user', 'password', 'your_db');
$myVar = $_GET["location"];
$sql = 'SELECT * FROM assets WHERE variable=?';
$query = $conn->prepare( $sql);
$query->bind_param('s',$myVar);
$result = $query->execute();
Try this code may be solve issues.
$conn= new mysqli("localhost","my_user", "my_password", "world");
$sql = 'SELECT * FROM assets WHERE variable='.$_POST["variable"];
mysqli_query($conn,$sql);
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 7 years ago.
(Edit:Guys, Before jumping to any conclusions, I'm asking how do you escape a query variable from the Example#2 from php.net website. I tried lot of ways but they all gave me errors. If you can please read that Example and post your version of that exact Example#2. Also please read about why they have that example there.)
I was searching for a reliable 'row:count' method to use with PHP PDO across multiple database types, and came across below code from php.net
http://php.net/manual/en/pdostatement.rowcount.php (See Example:#2)
It says to do a row count to see if an entry exists in a database using a SELECT statement, the error proof method is to use PDO::query() instead of PDOStatement::fetchColumn().
My question is I know how to bind and execute with PDO, but I don't know how to assign a user submitted variable($username) to this $sql statement and escape it successfully?
Is it possible to bind parameters to this $sql mehod using PDO?
try{
$conn = new PDO($dsn, $db_username, $db_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->db = $conn;
} catch(PDOException $e){
echo 'Error:'.$e;
}
public function usernameExists($username){
//Check db for a match.
$sql = "SELECT * FROM users WHERE username = '".$username."'";
$results = $this->db->query($sql);
if($results->fetchColumn() > 0){
//Matching username found in the db
return true;
}else{
//No matching username in db
return false;
}
}
You're looking for bindValue. With it, you can use a placeholder when writing your query, then pass the user's input afterward.
For example:
public function usernameExists($username){
//$result = $this->db->query('SELECT * FROM users WHERE username = ');
//Check db for a match.
$sql = "SELECT * FROM users WHERE username = :username";
$s = $conn->prepare($sql);
$s->bindValue(':username',$username);
$s->execute();
$results = $s->fetchAll();
if(count($results) > 0){
//Matching username found in the db
return true;
}else{
//No matching username in db
return false;
}
For more info, see the PHP manual.
You're going to want to use a parameterized query like this:
<?php
$value = "whatever";
$stmt = $dbh->prepare("SELECT * FROM TABLE_NAME where column_name = ?");
if ($stmt->execute(array($value))) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
?>
If you really wanted to quote+escape the string, then that's possible too. It even looks somewhat more legible with complex variable interpolation than your original string patching:
$sql = "SELECT * FROM users WHERE username = {$this->db->quote($username)}";
// ->quote itself adds ↑ 'quotes' around
Now of course: don't do that. Use a placeholder, and pass it per ->execute([$var]); instead. Strive for consistency.
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 7 years ago.
I don't know how to make this code safe. I tried to use mysql_real_escape_string in the query variable like
$query = "select * from products where id= " . mysql_real_escape_string($products);
but didn't work, also tried to escape in the products variable, but got the same result.
Any sugestions?
Thanks.
<?php
/ Define vars.
$conn = mysql_connect('localhost', 'test', 'test');
$products = isset($_GET["products"]) ? $_GET["products"] : "";
$query = "select * from products where id=$products";
// List elements.
if ($conn)
{
mysql_select_db('testsqli');
$result = mysql_query($query);
// Table head.
echo '<table cellspacing="5" cellpadding="5">';
echo '<tr>';
echo '<td>Description</td>';
echo '<td>Price</td>';
echo '</tr>';
// Empty table?
if (#mysql_num_rows($result)==0)
{
echo '<tr>';
echo '<td><i>That\'s all!</i></td>';
echo '</tr>';
}
// Listing data in table.
while ($row = #mysql_fetch_array($result))
{
echo '<td>'.$row['Description'].'</td>';;
echo '<td>'.$row['Price'].'</td>';;
}
echo '</table>';
}
?>
You still need to add quotes, (and use msqli instead) like:
$query = "select * from products where id='" . mysqli_real_escape_string($products)."'";
// or
$query = sprintf(
"select * from products where id='%s'",
mysqli_real_escape_string($products)
);
I'd use prepared statements instead of MySQL escaping. Escaping skips over some of the wildcards, such as '%' and '*' which could also provide unanticipated results.
$stmt = $dbh->prepare("SELECT * FROM PRODUCTS WHERE ID=?");
$stmt->bindParam(1, $products, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// call the stored procedure
$stmt->execute();
Also, keep in mind the following measures keep it safe:
Never connect to the database as a superuser or as the database owner. Use always customized users with very limited privileges.
Check if the given input has the expected data type. (In this case, verify that $products is formatted as expected, i.e. if your product catalog has indices of only nine characters, make sure it's not 100 characters long.) PHP has a wide range of input validating functions, from the simplest ones found in Variable Functions and in Character Type Functions (e.g. is_numeric(), ctype_digit() respectively) and onwards to the Perl compatible Regular Expressions support.
If the application waits for numerical input, consider verifying data with ctype_digit(), or silently change its type using settype(), or use its numeric representation by sprintf().
Reference: http://php.net/manual/en/security.database.sql-injection.php
This question already has answers here:
Can I bind an array to an IN() condition in a PDO query?
(23 answers)
MySQLi Bind Param with an array for IN [duplicate]
(2 answers)
Closed 9 years ago.
I'm trying to write code that basically finds your facebook friends that are on my website. I succeed in phpmyadmin running the query but for some reason when i try to run the code from php it doesn't work
Here's the php code. Whenever i take the $string echo and place it in mysql it works just fine, but for whatever reason when running it in php the query is not returning any results.
$fql = "SELECT uid FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = 100000903067831) AND is_app_user = 'true'";
$param = array(
'method' => 'fql.query',
'query' => $fql
);
$this->load->library('facebook');
echo $this->facebook->getLoginUrl();
$fqlResult = $this->facebook->api($param);
$userIDarray = array();
foreach($fqlResult as $result)
{
echo $result['uid']."<br>";
array_push($userIDarray, intval($result['uid']));
}
$string = implode(', ',$userIDarray);
echo $string;
$vars = array($string);
$query = $this->db->query("SELECT * FROM users WHERE users.facebook_id IN (?)", $vars);
echo var_dump($query);
foreach($query->result() as $data)
{
echo var_dump($data);
}
You cannot pass multiple parameters in a single ?.
You need to construct the options for IN yourself using concatenation.
Like so:
foreach($fqlResult as $result)
{
echo $result['uid']."<br>";
array_push($userIDarray, intval($result['uid']));
}
$string = implode(', ',$userIDarray);
$query = $this->db->query("SELECT * FROM users WHERE users.facebook_id
IN ('.$string.')");
Note that you need to make sure your items in the $userIDarray are properly escaped.
Because you're not using parameters, but you've injected these values into your SQL you are in danger of SQL injection attacks.
You are passing them through intval which guarantees that the strings will only contain 0..9 and - so you are safe from that here.
If the data is not numeric, you need use mysqli_real_escape_string to compensate for the fact that you're bypassing PDO's parameters.