This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Best way to prevent SQL Injection in PHP
In my website users can submit posts and delete their posts.
To delete a post, they follow the link /posts.php?deletid=X where X is the id of the post in database (for example: 1).
When clicked, it will run the following:
if(isset($_GET['deleteid'])) {
$deleteid = $_GET['deleteid'];
$sql = "DELETE from `posts` WHERE `id`=".mysql_real_escape_string($deleteid).";";
$query = mysql_query($sql);
header('Location: posts.php');
exit();
}
The problem is that it's vulnerable to the 1=1 SQL injection. If they type into the address bar /posts.php?deletid=1 OR 1=1;
it will delete all posts on database.
In this question: How can I prevent SQL injection in PHP?, I realized I need to use mysqli statements, and I tried to make it work but with no success..
Can someone please tell me exactly how I can prevent this with mysqli?
You need to have the value in quotes for mysql_real_escape_string to have any useful effect.
$sql = "DELETE from `posts` WHERE `id`='".mysql_real_escape_string($deleteid)."'";
Alternatively, instead of mysql_real_escape_string, which is intended for strings, try intval.
With MySQLi and prepared statements you do not need to worry about this, as a parameter cannot be replaced by 1 OR 1=1 (or if it is provided as the parameter value, then it’s interpreted as a string).
By using prepared statements, the mysql_* functions are on there way out and soon tobe deprecated, one should not be writing new code with these functions, refactor your code.
PDO
<?php
$db = new PDO("mysql:host=localhost;dbname=yourDB", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/*** prepare the SQL statement ***/
$query = $db->prepare("DELETE from `posts` WHERE `id`=:id;");
/*** bind the paramaters ***/
$query->bindParam(':id', $deleteid, PDO::PARAM_INT);
/*** execute ***/
$query->execute();
header('Location: posts.php');
exit();
?>
mysqli
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* create a prepared statement */
if ($stmt = $mysqli->prepare("DELETE from `posts` WHERE `id`=?")) {
/* bind parameters for markers */
$stmt->bind_param("i", $deleteid);
/* execute query */
$stmt->execute();
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
header('Location: posts.php');
exit();
?>
One thing first: if you can, it would be wise not to use mysql_* but e.g. mysqli_* functions or PDO, since the first are outdated. There you can use placeholders (?) instead of string concats. You don't have to care for quoting yourself there.
The easiest option in your example code would be to run all numbers through integer parsing (use intval).
if(isset($_GET['deleteid'])) {
$deleteid = $_GET['deleteid'];
$sql = "DELETE from `posts` WHERE `id`=".intval($deleteid).";";
$query = mysql_query($sql);
header('Location: posts.php');
exit();
}
Related
I have a table structure like this:
sender| receiver| message|date|time
----------------------------------
How do I select all the messages written on the same date, with them appearing at the top, just like Facebook Chat?
I've tried something like this:
<?php
$con=mysql_connect("localhost","root","");
$db=mysql_select_db ("chat",$con);
$query=" select * from chat where sender='$send'
and receiver='$rec' order by date";
$result=mysql_query($query);
while($r2=mysql_fetch_array($result))
echo "<div>{$r2['date']}</div>";
{
echo"<div>{$r2['message']}</div>";
}
?>
You're trying to run an SQL query directly from PHP, which you can't do - you'll need to connect to your database first. Then you need to pass the $send and $rec variables to your database, preferably through prepared statements to prevent SQL injection.
It depends on whether you're using MySQLi or PDO as to exactly how you should do that, but I'll assume you're not using the mysql_ constructor, as that was deprecated as of PHP 5.5, and is removed in PHP 7.
As such, here's an example of how to do this through MySQLi with prepared statements:
<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
$stmt = $mysqli->prepare(
"SELECT * FROM tablename WHERE sender = ? && receiver = ?");
$stmt->bind_param("ss", $send, $rec);
// "ss' is a format string, each "s" means string
// Each variable gets passed to the question marks, in order
$stmt->execute();
$stmt->bind_result($result);
You then have the results stored in $result, and are free to manipulate from there.
Hope this helps! :)
After a long time avoiding Prepared Statements I want to leave my comfort zone and update all my sites to mysqli, but I'm having a really hard time to achieve things that seem simple before...
Connection
$conn = mysqli_connect($host, $user, $password, $database)or die(mysqli_error($conn));
All my query's were built this way:
$id = 1;
$result = mysqli_query($conn, "SELECT * FROM users WHERE id = '$id'");
$row = mysqli_fetch_array($result);
Then I could print all needed fields:
Name: $row['name'];
Email: $row['email'];
Address: $row['address'];
City: $row['city'];
...
I've tried several ways to prepare, execute, bind and fetch the results in a simple way, or similar to what I was used to, but none of them work for me.
My statement is that bad? I mean, if I sanitize all itens before any Query or Insert my statement will remain insecure?
Can anyone show me a example of how can I use prepared statement but still be able to print my results individually, like: $row['name], $row['address'], $row['city']...
JUST TO UPDATE A FEW THINGS
This code works properly, my connection is ok and the $id is declared above my query (I've edited my question). My question is how can I "transform" this code into a mySQLi Prepared Statement and still be able to print results individually like $row['name'], $row['address']...
<?php
$mysqli = new mysqli("localhost", "username", "password", "db_name");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$id =1;
if ($stmt = $mysqli->prepare("SELECT name, email from users where id=?")) {
/* bind parameters for markers */
$stmt->bind_param("d", $id);
/* execute query */
$stmt->execute();
$stmt->bind_result($name, $email);
/* fetch value */
$stmt->fetch();
printf("%s has email %s", $name, $email);
/* close statement */
$stmt->close();
}
?>
May it help
i am using mysqli prepared statement to insert record in the table like this
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');
/* check connection */
if (!$link) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
/* execute prepared statement */
mysqli_stmt_execute($stmt);
if(mysqli_stmt_affected_rows($stmt) > 0){
//if insert is successful then get the insrted id.
}
/* close statement and connection */
mysqli_stmt_close($stmt);
/* close connection */
mysqli_close($link);
and would like to get the last inserted id , as the table has record_num field which is auto increment .
so my question is should i place connection name or the statement name inside the function.
i.e
1)
echo mysqli_insert_id($link);
Source: http://php.net/manual/en/mysqli.insert-id.php
2)
echo mysqli_stmt_insert_id($stmt);
Source: http://php.net/manual/en/mysqli-stmt.insert-id.php
which one is correct ?
which one will give me last insrted id by the $stmt ?
there are no other inserts are being done using the same stmt one the same page..*
Update:
according to the note from http://php.net/manual/en/mysqli-stmt.insert-id.php
I am doing only single insert so i guess i can use
mysqli_stmt_insert_id($stmt)
but while doing multiple inserts using prepared statements using
echo mysqli_insert_id($link);
is best practice.
You should use
mysqli_insert_id($link);
Because of this note on the PHP manual you referred us to
mysqli_stmt_insert_id
It should be noted that using mysqli_stmt->insert_id will not result in a unique ID being returned for each execution of a prepared insert statement. In practice, it appears that the first insertion ID is returned. If you are performing multiple inserts with the same prepared statement (one invocation of mysqli_stmt::prepare and multiple invocations of mysqli_stmt::execute() for a given statement), and need to keep the unique ID for each insert, use mysqli_connection->insert_id.
for procedural language you need to use below code,
mysqli_insert_id($link));
yes as you mention in 1 point.
Correct is 1) - link, as stated in documentation:
http://php.net/manual/en/mysqli.insert-id.php
I'm trying to include variables in my MYSQL SELECT WHERE query.
I want to be able to use variables, as well as the false symbol "!="
For example:
select * from XXX
where id != '$id'
Why is this not working, and how can I make this work?
It's better you use mysqli prepared statement or PDO since mysql_* functions are deprecated in recent PHP versions. Check how your query looks with mysqli prepared statement.
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$stmt = $mysqli->prepare("SELECT * XXX WHERE id != ?");
$stmt->bind_param( "d", $value);
// 'd' is a format integer, for string use 's'
$stmt->execute();
$stmt->bind_result($col1);
// then fetch and close the statement
As you are asking how can pass variable id in mysql query so check below, other wise so many guys have answered you for php etc.
set #id=4;
select * from XXX
where id != #id;
If you are using this code in php, you can use this
$query = "select * from XXX where id != {$id}";
OR
$query = "select * from XXX where id != '".$id."'";
If you are trying to use these variables in phpmyadmin, I think that is not possible.
$user = mysql_real_escape_string($_POST["userlogin"]);
mysql_connect("uritomyhost","myusername","password");
mysql_select_db('mydatabase');
mysql_query('UPDATE table SET field = field + ($userlogin)');
Is this the right way of getting userlogin from the post request and then inserting it to my SQL query?
Stop using outdated functions and use PDO instead.
$stmt = PDO::prepare('UPDATE table SET field = field + :field');
$stmt->execute(array('field' => $_POST["userlogin"]));
Read some information about PDO.
In short: it escapes your data for you, is quite consistent across databases and generally just easier.
you should use mysql_real_scape_string() just after connecting to database ...
so change your code to this :
mysql_connect("uritomyhost","myusername","password");
mysql_select_db('mydatabase');
$userlogin = mysql_real_escape_string($_POST["userlogin"]);
mysql_query("UPDATE table SET field = '$userlogin'");
Try like this.
$user = mysql_real_escape_string($_POST["userlogin"]);
mysql_connect("uritomyhost","myusername","password");
mysql_select_db('mydatabase');
mysql_query("UPDATE table SET field = value where user='$user'");
Try this
mysql_query("UPDATE table SET field = field + ('$user')");
However,
You might be updating all the fields in your table because you have no where in your UPDATE clause
Shouldn't it rather be
mysql_query("UPDATE table SET field = field WHERE user= '$user'");
I think you want to INSERT instead of using Update. Why field = field + ($userlogin)? This will concatenate the values. And one more thing please use PDO or MYSQLI
Example of using PDO extension:
<?php
$stmt = $dbh->prepare("INSERT INTO tanlename (field) VALUES (?)");
$stmt->bindParam(1, $user);
$stmt->execute();
?>
Use mysql_real_escape_string() after mysql connection and
Use double quotes
mysql_query("UPDATE table SET field = field + ({$userlogin})");
Use mysqli_query for you queries(notice the i) and use prepared statements. Using prepared statements is more secure than using straight queries and including the variable in the query string. Moreover, mysql will be deprecated soon. Example :
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$city = "Amersfoort";
/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {
/* bind parameters for markers */
$stmt->bind_param("s", $city);
/* execute query */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($district);
/* fetch value */
$stmt->fetch();
printf("%s is in district %s\n", $city, $district);
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
?>