I have many functions like
updateUser($id,$username,$email)
updateMusic($id, $music)
etc...
Is there a generic function to avoid SQL injections ?
I just want to avoid using mysql_real_escape_string for each parameter I have
$username = mysql_real_escape_string($username);
$email= mysql_real_escape_string($email);
$music= mysql_real_escape_string($music);
ALWAYS use prepared statements
Do NOT use mysql driver, use mysqli or PDO
You should use parameterization and let the database driver handle it for you, i.e. with PDO:
$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password);
$stmt = $dbh->prepare('INSERT INTO REGISTRY (name, value) VALUES (:name, :value)');
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
Code from Bobby-Tables.
you may use,
list($id,$music) = array_map('mysql_real_escape_string',array($id,$music))
but prepared statements rocks
No there isn't, but you can parse all your inputs ( eg. GET and POST ) at beggining of the script
Related
I find ezSQL library very useful but as far as I see there is no implementation of prepared statements in it, am I right? Or is there something I don't know?
I have checked out the help file which I downloaded from http://justinvincent.com/ezsql
For example: I have some queries like
$stmt = $conn->prepare("INSERT INTO gecici_magaza_detay VALUES ($geciciMagazaId,?,?,?,?)");
$stmt->bind_param("iiss",$gunId,$acikMi,$girisSaati,$cikisSaati);
for($j=0; $j<7; $j++) {
$gunId = $j+1;
$acikMi = (empty($acilis[$j]) || empty($kapanis[$j])) ? 0 : 1;
$girisSaati = $acikMi ? $acilis[$j] : null;
$cikisSaati = $acikMi ? $kapanis[$j] : null;
$stmt->execute();
}
where $conn is a mysqli object.
$conn = new mysqli($servername, $username, $password, $dbname);
but I want to get rid of it completely and use only my $db object which is:
$db = new ezSQL_mysqli();
I hope there is a way of using prepared statements with ezSQL, that would make me more comfortable, otherwise I'll have to use both.
I know this is an old question, but there are options for prepared statements from v3.08+.
When you create your connection you simply use $db->prepareOn();. Here's an example using this code
// To get SQL calls to use prepare statements
$db->prepareOn(); // This needs to be called at least once at instance creation
$db->query_prepared('INSERT INTO profile( name, email, phone) VALUES( ?, ?, ? );', [$user, $address, $number]);
$db->query_prepared('SELECT name, email FROM profile WHERE phone = ? OR id != ?', [$number, 5]);
$result = $db->queryResult(); // the last query that has results are stored in `last_result` protected property
foreach ($result as $row) {
echo $row->name.' '.$row->email;
}
More information can be found on the new Wiki
No, there isn't any built-in prepared statement feature in ezsql.
Use $db->escape() function for unsafe variables. This is the safest option available.
I have some working code to take out the tediousness of binding each variable to its parameter manually in a pdo prepared statement. I loop through the $_POST array and bind the variables to the params dynamically based on the name attributes from the html form.
My question is, is it safe to do this? Am I open to SQL injection?
Here is my code -
if( !empty($_POST) ){
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("INSERT INTO planes (name, description) VALUES(:name, :description)");
foreach($_POST as $key => &$value){
$key = ':'.$key;
$stmt->bindParam($key, $value);
}
$stmt->execute();
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
$conn = null;
}
Yes, it's safe. If you're using parameterized queries, you won't be vulnerable to injection attacks.
That being said, it seems that you're reinventing the wheel here, which is most often not the right way to do things. However; that's outside the scope of your question.
Also please see this very similar question where the accepted answer has this to say:
Use prepared statements and parameterized queries. These are SQL statements that are sent to and parsed by the database server separately from any parameters. This way it is impossible for an attacker to inject malicious SQL.
I'm trying to use PDO to avoid sql injections and have been looking and searching around for examples and this is what I've come up with, but there are some kind of error somewhere. The database is not getting updated and I get and sql error, but it wont print the details.
elseif (isset($_POST["bilnr"])) {
$name = $_POST['name']; $mobil = $_POST['mobil']; $bilnr = $_POST['bilnr']; $regnr = $_POST['regnr']; $userid = $_COOKIE[userid]; $username = $_COOKIE[user];
$sql=$oDB->Prepare("UPDATE members SET name=:name, mobil=:mobil, bilnr=:bilnr, regnr=:regnr WHERE id=:userid AND username=:username");
$sql->execute(array(':userid' => $userid);
if (!$sql) {
echo "\nPDO::errorInfo():\n";
print_r($oDB->errorInfo());
}
echo "<p class=\"red\">Informasjonen er oppdatert!</p>";
mysqli_close($con); }
If or when I remove the mysqli_close string something crashes and the page just turns blank with no errors. Also with the code above the updates being made in the form dont get into the database.
and the PDO connection in a separate file which is being included
$oDB=new PDO("mysql:host=$host;dbname=$db_name", $username, $password);
Here is the updated code
elseif (isset($_POST["bilnr"])) {
$name = $_POST['name']; $mobil = $_POST['mobil']; $bilnr = $_POST['bilnr']; $regnr = $_POST['regnr']; $userid = $_COOKIE[userid]; $username = $_COOKIE[user];
$sql=$oDB->Prepare("UPDATE members SET name=:name, mobil=:mobil, bilnr=:bilnr, regnr=:regnr WHERE id=:userid AND username=:username");
$sql->execute(array(':userid' => $userid,
':name' => $name,
':mobile' => $mobile,
':bilnr' => $billnr,
':regnr' => $regnr,
':username' => $username));
if (!$sql) {
echo "\nPDO::errorInfo():\n";
print_r($oDB->errorInfo());
}
echo "<p class=\"red\">Update Done!</p>";
mysqli_close($con); }
The next problem is to get the values into the database, as it is now I don't receive any errors so I'm not sure whats wrong.
UPDATE
It works, was just some typo's in the array variables :)
First, you can't mix mysqli and PDO. Second, the problem with your query is that you have 6 placeholders, but you're only filling in one of them when you call execute(). It should be:
$sql->execute(array(':userid' => $userid,
':name' => $name,
':mobile' => $mobile,
':bilnr' => $billnr,
':regnr' => $regnr,
':username' => $username));
The first argument for mysqli_query must be a string (representation of an SQL query) but you are passing it a PDO prepared query.
Don't mix and match multiple database libraries.
Use PDO or mysqli_.
You don't need mysqli_* functions anymore, scrap 'em (only when you're using PDO) :) When you're using PDO, mysql_* and mysqli_* don't work when combining them. I recommend you to use PDO and not mysql functions anymore. PDO is now well established and is the preferred way.
$sql = "
INSERT INTO table (name)
VALUES (:name)
";
//Here you prepare the SQL (you already did that correctly).
$stmt = $db->prepare($sql);
//You can choose to use bindParam, bindValue or include it in the array (as you do it).
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$name = 'John';
$stmt->execute();
This is an example how to insert something into a MySQL database with PDO.
Do I need to use mysql_real_escape_string() on my input (such as $_POST and $_GET) when I use the PDO library?
How do I properly escape user input with PDO?
If you use PDO you can parametize your queries, removing the need to escape any included variables.
See here for a great introductory tutorial for PDO.
Using PDO you can seperate the SQL and passed parameters using prepared statements, this removes the need to escape strings, as because the two are held seperately then combined at execution, the parameters are automatically handled as stings, from the above source:
// where $dbh is your PDO connection
$stmt = $dbh->prepare("SELECT * FROM animals WHERE animal_id = :animal_id AND animal_name = :animal_name");
/*** bind the paramaters ***/
$stmt->bindParam(':animal_id', $animal_id, PDO::PARAM_INT);
$stmt->bindParam(':animal_name', $animal_name, PDO::PARAM_STR, 5);
/*** execute the prepared statement ***/
$stmt->execute();
Note: sanitization occurs during variable binding ($stmt->bindParam)
Other resources:
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
http://www.phpeveryday.com/articles/PDO-Prepared-Statement-P550.html
http://php.net/manual/en/pdo.prepared-statements.php
The important point when using PDO is:
PDO will only sanitize it for SQL, not for your application.
So yes, for writes, such as INSERT or UPDATE, it’s especially critical to still filter your data first and sanitize it for other things (removal of HTML tags, JavaScript, etc).
<?php
$pdo = new PDO(...);
$stmt = $pdo->prepare('UPDATE users SET name = :name WHERE id = :id');
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT); // <-- filter your data first
$name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING); // <-- filter your data first
$stmt->bindParam(':id', $id, PDO::PARAM_INT); // <-- Automatically sanitized for SQL by PDO
$stmt->bindParam(':name', $name, PDO::PARAM_STR); // <-- Automatically sanitized for SQL by PDO
$stmt->execute();
Without sanitizing the user input, a hacker could have saved some javascript into your database and then, when output it into your site you would have been exposed to a threat!
http://www.phptherightway.com/#pdo_extension
I'm using PHP with MySQLi, and I'm in a situation where I have queries like
SELECT $fields FROM $table WHERE $this=$that AND $this2=$that2
So far I've written some code that splices up an array that I give it, for example:
$search = array(name=michael, age=20) //turns into
SELECT $fields FROM $table WHERE name=michael AND age=20
Is there a more efficient way to do this?
I'm rather worried about MySQL injections - this seems very vulnerable.
Thanks!
Oddly enough, the title to your question is basically the answer to it. You want to do something like this, using mysqli parameterized queries:
$db = new mysqli(<database connection info here>);
$name = "michael";
$age = 20;
$stmt = $db->prepare("SELECT $fields FROm $table WHERE name = ? AND age = ?");
$stmt->bind_param("si", $name, $age);
$stmt->execute();
$stmt->close();
More information in the mysqli section of the manual, specifically the functions related to MySQLi_STMT.
Note that I personally prefer using PDO over mysqli, I don't like all the bind_param / bind_result stuff that mysqli does. If I have to use it I write a wrapper around it to make it work more like PDO.