This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 8 years ago.
Is there a way to restrict php pdo execute() to run just the first sql statement?
For instance running
SELECT * FROM customer;DROP TABLE invoice
will return all customers but it will also delete the invoice table.
I have a situation where I need a whole SQL statement from a user but it must be a SELECT and nothing additional.
My example is just one of many that could be maliciously entered. It might include additional DROP, UPDATE, DELETE statements etc.
A prepared statement will simply replace ?s with values. It will not stop dangerous SQL statemets being passed to it.
This would not be a problem if there was a way to restrict php pdo execute() to run just the first sql statement?
IF your trying to prevent SQL injection, prepare statements can handle it.
you can use something like this to prevent SQL injection
$stmt = $db->prepare("SELECT * FROM table WHERE id=? AND name=?");
$stmt->bindValue(1, $id, PDO::PARAM_INT);
$stmt->bindValue(2, $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Related
This question already has answers here:
How to echo a MySQLi prepared statement?
(6 answers)
Closed 5 years ago.
Is there any function that will return the prepared query string after processing all the parameters. like
$stmt = $conn->prepare("SELECT full_name FROM user_info where user_id = ?");
$stmt->bind_param("s", $user_id);
Can I see the final query string that will execute?
If the driver is capable of using prepared statements, if it doesn't require emulation, then the final query executed is the prepared statement.
If you want to find out what was executed, you need to turn on the general query log on your server. That can be very, very noisy and fill up your disk quickly on a busy server.
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 8 years ago.
$query = $this->db->prepare("INSERT INTO `images` (`anunt`, `image_location`) VALUES(?, ?)");
$query->bindValue(1, $iddd);
$query->bindValue(2, $image_location);
try{
$query->execute();
or this
$ret = sql_query("INSERT INTO images (anunt, image_location) VALUES ('" .$iddd. "', '" .$image_location. "')");
Or another way maybe?
What advantages are with the bind one? I read something that it's hard to sql inject.
Databse pre-optimzations
When you initialize a prepared statement, the DBMS actually pre-optimizes the database and compiles your query. This would be useful if you plan to make multiple bound queries with the same prepared statement.
SQL Injection prevention
The PHP SQL drivers will escape any literals inside a bound value, to prevent SQL injection.
This question already has answers here:
What is the question mark's significance in MySQL at "WHERE column = ?"?
(4 answers)
How can I prevent SQL injection in PHP?
(27 answers)
Closed 8 years ago.
I need help to figure out what this sentence mean:
SELECT id, username, password FROM users WHERE email = ?LIMIT 1
I know what LIMIT 1 means but what the '= ?' is for ?
It's a prepared statement.
A prepared statement or a parameterized statement is used to execute the same statement repeatedly with high efficiency.
The prepared statement execution consists of two stages: prepare and execute. At the prepare stage a statement template is sent to the database server. The server performs a syntax check and initializes server internal resources for later use.
Prepare is followed by execute. During execute the client binds parameter values and sends them to the server. The server creates a statement from the statement template and the bound values to execute it using the previously created internal resources.
A prepared statement can be executed repeatedly. Upon every execution the current value of the bound variable is evaluated and sent to the server. The statement is not parsed again. The statement template is not transferred to the server again.
Every prepared statement occupies server resources. Statements should be closed explicitly immediately after use. If not done explicitly, the statement will be closed when the statement handle is freed by PHP.
Using a prepared statement is not always the most efficient way of executing a statement. A prepared statement executed only once causes more client-server round-trips than a non-prepared statement.
This example performs an INSERT query by substituting a name and a value for the positional ? placeholders.
<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
I recommend reading that entire tutorial. You should also check out PDO.
Your query:
SELECT id, username, password FROM users WHERE email = ? LIMIT 1
? sign means placeholder.
I suppose, you use pdo. When you will execute your query
$email = // get some email
$stmt = $dbh->prepare("SELECT id, username, password FROM users WHERE email = ? LIMIT 1");
$stmt->bindParam(1, $email);
value of variable $email will be placed insetead of ? like:
SELECT id, username, password FROM users WHERE email = 'bob#gmail.com' LIMIT 1
You can find more information about it here
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
I've build a website that will be going live soon and just have a couple questions about preventing SQL injection, I understand how to use mysqli_real_escape_string but I'm just wondering if I have to use that on all variables that I'm getting for my SQL statement and do I have to use it when I'm doing select statements also or just on insert update and delete? Also what other security would you recommend me implementing before I put the site live, thanks in advance for any help!
Any query can be injected whether it's read or write, persistent or transient. Injections can be performed by ending one query and running a separate one (possible with mysqli), which renders the intended query irrelevant.
Any input to a query from an external source whether it is from users or even internal should be considered an argument to the query, and a parameter in the context of the query. Any parameter in a query needs to be parameterized. This leads to a properly parameterized query that you can create a prepared statement from and execute with arguments. For example:
SELECT col1 FROM t1 WHERE col2 = ?
? is a placeholder for a parameter. Using mysqli, you can create a prepared statement using prepare, bind a variable (argument) to a parameter using bind_param, and run the query with execute. You don't have to sanitize the argument at all (in fact it's detrimental to do so). mysqli does that for you. The full process would be:
$stmt = $mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();
There is also an important distinction between parameterized query and prepared statement. This statement, while prepared, is not parameterized and is thus vulnerable to injection:
$stmt = $mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");
To summarize:
All Queries should be properly parameterized (unless they have no parameters)
All arguments to a query should be treated as hostile as possible no matter their source
Recently one hacker tried to slow my website using sleep injection. Although we are using precautions like mysql_real_escape_string() to cover most of vulnerable inputs. We are passing id of the product through query string and it makes the command as:
$id = mysql_real_escape_string($_REQUEST['id']);
$qry = "Select * from products where id = ".$id;
but hacker tried to provide input as
?id=3 and sleep(4)
and query becomes
Select * from products where id = 3 and sleep(4);
Although there are some possible solutions like
Check if the product id is numeric or not
Remove word sleep from input using some customized function
Is there any other method to stop this? What is the best method to prevent sleep injections?
You are not escaping correctly. mysql_real_escape_string is for escaping SQL string syntax correctly, but you are simply embedding the value as bare value, not as SQL string. You need:
$qry = "SELECT * FROM products WHERE id = '$id'";
Note the quotes around the id in the query.
If the id is numeric though, casting to a number would be more sensible:
$id = (int)$_GET['id'];
The best method to prevent SQL injections is to use current technology. The MySQL mysql_ family of functions is deprecated and will be removed from PHP in a future revision.
You should use prepared statements with either MySQLi or PDO instead.
These technologies use prepared statements and parameterized queries. SQL statements are parsed by the database server separately from any parameters. It is impossible for an attacker to inject malicious SQL.
You basically have two options to achieve this:
MySQLi:
$stmt = $dbConnection->prepare('SELECT * FROM table WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
PDO:
$stmt = $pdo->prepare('SELECT * FROM table WHERE name = :name');
$stmt->execute(array(':name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
What happens is that the SQL statement you pass to prepare is parsed and compiled by the database server. By specifying parameters (either a ? or a named parameter like :name) you tell the database engine what you want to filter on. Then when you call execute the prepared statement is combined with the parameter values you specify.
The important thing here is that the parameter values are combined with the compiled statement, not a SQL string. SQL injection works by tricking the script into including malicious strings when it creates SQL to send to the database. So by sending the actual SQL separately from the parameters you limit the risk of ending up with something you didn't intend. Any parameters you send when using a prepared statement will just be treated as strings (although the database engine may do some optimization so parameters may end up as numbers too, of course).
This is wrong question to ask.
"How to prevent mysql injections?" it has to be. Sleep or not sleep - it doesn't matter.
And there are plenty of answers on this question already
if you want a canonical one, then How can I prevent SQL injection in PHP?
if you want to understand, how it works, here I explained it in details
you should convert your queries into "prepared statements" using PDO or mysqli.