Could someone show me how I would go about converting my current UPDATE tablename SET column into a safe and secure statement using PDO to protect against SQL injection ? I am trying to better understand binding and PDO but am having trouble with setting it up with PDO. Here is what I currently have with regular msqli
<?php
session_start();
$db = mysqli_connect("hostname", "username", "password", "dbname");
$username = $_SESSION['jigowatt']['username'];
mysqli_query($db, "UPDATE login_users SET Points=Points+15 WHERE username='$username'");
?>
MySQL
You don't need PDO or MySQLi for that. mysql_real_escape_string protect you against sql injection:
$name = 'Bob';
$age = 25;
$description = "' OR 1=1"; // a SQL injection string
$query = "
UPDATE people(name, age, description)
VALUES ('".mysql_real_escape_string($name)."', ".(int) $age.", '".mysql_real_escape_string($description)."');";
// a secure query execution
$result = mysql_query($query);
PDO
With PDO::quote()
PDO::quote() is equal to mysql_real_escape_string:
$pdo = new PDO(...);
$name = 'Bob';
$age = 25;
$description = "' OR 1=1"; // a SQL injection string
$query = "
UPDATE people(name, age, description)
VALUES (".$pdo->quote($name).", ".(int) $age.", ".$pdo->quote($description).");";
// a secure query execution
$result = $pdo->query($query);
With prepared statements
You can use prepared statements. You could put the hole query inside the prepared statement, but it is better to use placeholders for variables:
$pdo = new PDO(...);
$name = 'Bob';
$age = 25;
$description = "' OR 1=1"; // a SQL injection string
$query = "
UPDATE people(name, age, description)
VALUES (:name, :age, :description);";
$stmt = $pdo->prepare($query); // prepare the query
// execute the secure query with the parameters
$result = $pdo->execute(array(
':name' => $name,
':age' => $age,
':description' => $description,
));
Related
I'm building an API with a bunch of db queries. To avoid repeating some pre established values in each query I created some PHP constants. However I'm not sure about the right way to include them in Mysqli prepared statements. I know that constants can't be passed by reference. So I wonder if I should create a variable for the query that includes the constants or if I could just pass the string directly with the constants to the prepare() function. So it is okay if I do it like this or should I create a variable and storing the string there prior to calling prepare()?
$stmt = $this->conn->prepare("SELECT city FROM masters WHERE email = ? AND estado != '" . STATE_INACTIVE . "'");
$stmt->bind_param("s", $email );
VERSUS
$query = "SELECT city FROM masters WHERE email = ? AND estado != '" . STATE_INACTIVE . "'";
$stmt = $this->conn->prepare($query);
$stmt->bind_param("s", $email );
Since you're using a constant value, you're not exposing yourself to potential SQL injection attacks by concatenating the value into your query. So, I think what you have is fine. Your other option would be to assign the constant value to a variable and bind it, like this:
$query = "SELECT city FROM masters WHERE email = ? AND estado != ?";
$inactiveState = STATE_INACTIVE;
$stmt = $this->conn->prepare($query);
$stmt->bind_param("ss", $email, $inactiveState);
It's worth pointing out as well here that this is mysqli, not PDO. If you were using PDO you could do this:
$query = "SELECT city FROM masters WHERE email = ? AND estado != ?";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(1, $email, PDO::PARAM_STR);
$stmt->bindValue(2, STATE_INACTIVE, PDO::PARAM_STR);
This is my first query, i want to use the multiple itemID's extracted for another query.
$conn = new mysqli(server, dbuser, dbpw, db);
$email = $_GET['email'];
$querystring = "SELECT itemID from mycart where email = '".$email."' ";
$result = $conn->query($querystring);
$rs = $result->fetch_array(MYSQLI_ASSOC);
The second query that need
$query = "SELECT * from CatalogueItems where itemID = '".$itemID."'";
How do i make these 2 query run?
Firstly, Your code is open to SQL injection related attacks. Please learn to use Prepared Statements
Now, from a query point of view, you can rather utilize JOIN to make this into a single query:
SELECT ci.*
FROM CatalogueItems AS ci
JOIN mycart AS mc ON mc.itemID = ci.itemID
WHERE mc.email = $email /* $email is the input filter for email */
PHP code utilizing Prepared Statements of MySQLi library would look as follows:
$conn = new mysqli(server, dbuser, dbpw, db);
$email = $_GET['email'];
$querystring = "SELECT ci.*
FROM CatalogueItems AS ci
JOIN mycart AS mc ON mc.itemID = ci.itemID
WHERE mc.email = ?"; // ? is the placeholder for email input
// Prepare the statement
$stmt = $conn->prepare($querystring);
// Bind the input parameters
$stmt->bind_param('s', $email); // 's' represents string input type for email
// execute the query
$stmt->execute();
// fetch the results
$result = $stmt->get_result();
$rs = $result->fetch_array(MYSQLI_ASSOC);
// Eventually dont forget to close the statement
// Unless you have a similar query to be executed, for eg, inside a loop
$stmt->close();
Refer to the first query as a subquery in the second:
$query = "SELECT * from CatalogueItems WHERE itemID IN ";
$query .= "(" . $querystring . ")";
This is preferable to your current approach, because we only need to make one single trip to the database.
Note that you should ideally be using prepared statements here. So your first query might look like:
$stmt = $conn->prepare("SELECT itemID from mycart where email = ?");
$stmt->bind_param("s", $email);
This creates a variable out of your result
$query = "SELECT itemID FROM mycart WHERE email = :email";
$stm = $conn->prepare($query);
$stm->bindParam(':email', $email, PDO::PARAM_STR, 20);
$stm->execute();
$result = $stm->fetchAll(PDO::FETCH_OBJ);
foreach ($result as $pers) {
$itemID = $pers->itemID;
}
I'm quite new to php and previously have just been using mysqli for my queries. However I always see people saying to use prepared statements instead, so i went through my project in an effort to change all my queries into prepared statements. This particular query is not updating
$email = $userDetails['email'];
$token = bin2hex(random_bytes(16));
$username = $userDetails['username'];
$timestamp = date('Y/m/d H:i:s');
$sql = "UPDATE users SET token = ? AND timestamp = ? WHERE email = ?";
$stmt = mysqli_prepare($connect, $sql);
mysqli_stmt_bind_param($stmt,"sss",$token,$timestamp,$email);
mysqli_stmt_execute($stmt);
You are using AND instead of , in your UPDATE query :
$sql = "UPDATE users SET token = ?, timestamp = ? WHERE email = ?";
I have my database and im retrieving data like below.But i need to retrieve them more secure for prevent by the sql injections.in my script im getting all the fields like below and in echo out in a place where i want to show the fields.
Please tell me a secure way to get them.Please help me,any help much appreciated.
And i want to use while function to retrieve all the data.Please help me
<?php
$getdata ="SELECT * FROM tblname ODER BY ";
$result = mysql_query($getdata);
$row = mysql_fetch_array($result);
$bookName = $row['bookName'];
$timestamp = $row['timestamp'];
$Country = $row['Country'];
$Category = $row['Category'];
$Price = $row['Price'];
$Photo1name = $row['Photo1name'];
?>
SQL injection can only be performed if you use user input.
So you are safe with that when you read from database. With your code you must use mysql_real_escape_string, but I suggest using PDO and it's prepared statements to auto-escape values.
$sth = $dbh->prepare('SELECT * FROM tblname WHERE name = :name ORDER BY');
$sth->execute([':name' => $_POST['name']]);
$result = $sth->fetchAll();
To sanitize your output try using htmlentities or strip_tags functions.
To prevent SQL injection you have to escape values:
$pdo = PDO('mysql:host=localhost;dbname=test', 'root', 'iAmD4B3st!');
$sql = $pdo->prepare("INSERT INTO my_table (name, surname) VALUES (:name, :surname)");
$sql->execute([
':name' => isset($_POST['name']) ? $_POST['name'] : '',
':surname' => isset($_POST['surname']) ? $_POST['surname'] : '',
]);
I am trying to run an sql query using PDO prepared statements
$sql = "INSERT INTO tickets (ticketnumber, status) VALUES (1234, Open) ";
$stmt = $connection->prepare($sql);
$stmt->execute();
But it is just not inserting. What have I done wrong?
Here is my connection:
$host = "localhost";
$db_name = "";
$username = "";
$password = "";
$connection = new PDO("mysql:host={$host};dbname={$db_name}", $username, $password);
Try this. It's much more secure.
Make sure you have included your connection file.
EDITED
$sql = "INSERT INTO `tickets` (ticketnumber, status) VALUES (:ticketnumber, :status)";
$stmt = $connection->prepare($sql);
$stmt->bindValue(':ticketnumber', 1234, PDO::PARAM_INT);
$stmt->bindValue(':status', 'Open', PDO::PARAM_STR);
$stmt->execute();
Also, the named parameters used above must NOT be enclosed in quotes. If you do so, it'll be treated as a literal string and not a named parameter.
You need to use quotes on strings before inserting them into a database.
Why use prepare if you're not preparing your data before sending it to the database?