This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 7 years ago.
I have a simple survey page that I was trying to make. Everything worked well except when I used a single quote in my comment on the survey page. When I had a comment with a single quote in it, the DB query wouldn't insert into the DB.
After some Googleing, I assumed I had to escape the string before inserting it into the DB. I used mysqli_real_escape_string to escape the string before INSERTing into the DB, but that doesn't seem to have helped.
Here is my code that inserts the user's comments into the DB ($con not shown for security)
mysqli_real_escape_string($con,$_POST['question_1']);
mysqli_real_escape_string($con,$_POST['question_2']);
mysqli_real_escape_string($con,$_POST['question_3']);
mysqli_real_escape_string($con,$_POST['question_4']);
mysqli_real_escape_string($con,$_POST['question_5']);
mysqli_query($con, "INSERT INTO feedback (question_1, question_2, question_3, question_4, question_5) VALUES ('$_POST[question_1]', '$_POST[question_2]', '$_POST[question_3]', '$_POST[question_4]', '$_POST[question_5]')");
Again, this only happens when the comment contains a single quote. Any suggestions? Did I escape the string incorrectly?
You've misunderstood what is happening here
mysqli_real_escape_string($con,$_POST['question_1']);
This function returns an escaped string. You then use this string in your SQL
$question1 = mysqli_real_escape_string($con,$_POST['question_1']);
//Do your other escapes here
mysqli_query($con, "INSERT INTO feedback (question_1, question_2, question_3, question_4, question_5)
VALUES ('$question1', ...)");
A better solution here is prepared statements. This doesn't require you to escape anything. Data is sent separately and treated appropriately
$prep = mysqli_prepare($con, 'INSERT INTO feedback (question_1, question_2, question_3, question_4, question_5)
VALUES (?, ?, ?, ?, ?)');
mysqli_stmt_bind_param($prep, "sssss", $_POST['question_1'], $_POST['question_2'], $_POST['question_3'], $_POST['question_4'], $_POST['question_5']);
mysqli_stmt_execute($prep);
Related
I'm new here. I started PHP recently and I am wondering how I could insert variables, and put them into single quotes, into a double quotes string.
Here's what I tried :
$query = "INSERT INTO Table (Name, Activity) VALUES ('$name', '$activity');";
But when I check $query, it contains that : INSERT INTO Table (Name, Activity) VALUES (,);. I don't understand why it does that because when, instead of writing the above code, I write this one : $query = "INSERT INTO Table (Name, Activity) VALUES ($name, $activity);"; (without the single quotes), the string contains this : INSERT INTO Table (Name, Activity) VALUES (Robert, Book-seller);. Does anybody have a clue ?
how I could insert variables, and put them into single quotes, into a double quotes string.
Don't do that. It leaves you vulnerable to SQL injection attacks. Instead use prepared statements with bound parameters as described in this post.
I tried your statement:
$query = "INSERT INTO Table (Name, Activity) VALUES ('$name', '$activity');";
And It worked perfectly with me. I guess you need to check the values you passing in $name and $activity. (for Robert, Book-Seller its working nicely).
Still You may try this. It might help:
$query = "INSERT INTO Table (Name, Activity) VALUES (\"$name\", \"$activity\");";
And a note for caution: as Alex Howansky says, don't do that. it leaves you vulnerable to SQL injection attacks.
Hope it helps. All the best!
Hello i'm a beginner so please at least try to give me a hint,a example.
English isn't my main language so please endure it.
If somebody type " Hello my name is J'hon ' the text don't insert in database, but if he type 'Hello my name is jhon' it does. I think it is something about '
Ok so i'm having the problem that if someone types
'Hello my name is J[color=#FF0000]'[/color]hon J'onz. ' is not inserted in the database..
This is the script:
mysqli_query($DB_H, "INSERT INTO tickets (name, continutscurt, continut,type,status) VALUES ('".$_SESSION['username']."', '".$_POST['titlu']."', '".$_POST['continut']."', $numar, 0)");
You should really use prepared statements when dealing with any kind of user-input. If you for any weird reason isn't using prepared statements, take a look at the function mysqli::real_escape_string. This will deal with special characters, such as ', which may break the SQL.
With using prepared statements, your code would look like
if ($stmt = $DB_H->prepare("INSERT INTO tickets (`name`, continutscurt, continut, `type`, `status`) VALUES (?, ?, ?, ?, ?)")) {
$stmt->bind_param("ssssi", $_SESSION['username'], $_POST['titlu'], $_POST['continut'], $numar, 0);
$stmt->execute();
$stmt->close();
} else {
echo mysqli_error($DB_H);
}
If you however want to use mysqli::real_escape_string, you'll need to bind the SESSIONs and POSTs to a variable where in you insert instead, like this (you can also do it directly in the query, but this makes for cleaner code).
$username = mysqli_real_escape_string ($DB_H, $_SESSION['username']);
$titlu = mysqli_real_escape_string ($DB_H, $_POST['titlu']);
$continut = mysqli_real_escape_string ($DB_H, $_POST['continut']);
$numar = mysqli_real_escape_string ($DB_H, $numar);
if (!mysqli_query($DB_H, "INSERT INTO tickets (`name`, continutscurt, continut, `type`, `status`) VALUES ('$username', '$titlu', '$continut', '$numar', 0")) {
echo mysqli_error($DB_H);
}
I also put backticks ` around name, status and type, as these are keywords in SQL. This isn't strictly necessary, but it's good practice with words that are listed as either reserved words or keywords, more info on this list of keywords.
You shouldn't take for granted that your queries are successful, so I added an if-block around them. Errors shouldn't be displayed unless in production/development.
References:
http://php.net/manual/en/mysqli.real-escape-string.php
http://php.net/manual/en/mysqli.prepare.php
How can I prevent SQL injection in PHP?
https://dev.mysql.com/doc/refman/5.7/en/keywords.html
The issue is SQL Injection.
You have potentially unsafe values being included within the SQL text.
To see this, break up the code a little bit.
$sql = "INSERT INTO tickets ...'" . $val . "' ... ";
echo $sql;
The echo is there just as a way to see what's going on, for you to examine the contents of the string containing the SQL text. And then take that string over to another client, and test it. And you will see what the the problem is.
... VALUES ( ..., 'J'onz. ', ...
isn't valid. That single quote is ending the string, so the string is just 'J', and the next part, MySQL is going to try to interpret as part of the SQL, not the string value. (This is a nefarious vulnerability. Cleverly constructed strings and wreak havoc on your application and your database.)
One approach to fixing that is to sanitize the values, so they can be safely included.
... VALUES ( ..., 'J\'onz. ', ...
^^
... VALUES ( ..., 'J''onz. ', ...
^^
As a simple demonstration try these queries:
SELECT 'J\'onz. '
SELECT 'J''onz. '
SELECT 'J'onz. '
(The first two will return the string you expect, and the third will cause an error.)
The take away is that potentially unsafe values that are going to included in the text of a SQL statement need to be properly escaped. Fortunately, the MySQL client library includes mysqli_real_escape_string function. Variables that may potentially contain a single quote character can be run through that function, and the return from the function can be included in the SQL text.
$sql = "INSERT INTO tickets ...'"
. mysqli_real_escape_string($DB_H,$val)
. "' ... ";
Again, echo out the $sql and you can see that a single quote has been escaped, either by preceding it with a backslash character, or replacing it with two sinqle quotes.
There's a much better pattern than "escaping" strings. And that's to use prepared statements with bind placeholders.
The SQL text can be a static string:
$sql = 'INSERT INTO mytable (mycol) VALUES ( ? )'
And then you msyqli_prepare the statement.
And then supply values for the placeholders with a call to mysqli_bind_param.
And then call mysqli_execute.
With this pattern, we don't need to mess with running the "escape string" function to sanitize the inputs.
I am using mysqli prepared statement to insert values into the database. I know that this extension handles characters escaping properly.
I have a file path : images/serveover/Bellini 83.png, what I am expecting to see after insert is the file path with escaped characters in the database, something like images\/serveover\/Bellini 83.png but I only see the image path as is.
How can I make sure that my string has been properly escaped? Is this view standard in phpMyAdmin where It does not show escaped characters or is it just hiding them on view?
Below is my insert prepared statement with params where all the values are being filled properly :
$insertQuery = $conn -> prepare("INSERT INTO images (image_id, image_date_created, image_date_modified, image_title, image_src, category_id, image_status, image_external_file, another_id) VALUES (null, NOW(), CURRENT_TIMESTAMP, ?, ?, ?,'A', ?, ?)");
if($insertQuery )
{
$insertQuery -> bind_param("ssisi", $title, $image, $row["category_id"], $file, $row["id"]);
$insertQuery -> execute();
$insertQuery -> close();
}
As long as you're dealing with strings, the escaping process simply instructs MySQL to ignore the special properties of a character and treat it like a normal character.
Bob\'s special string
Is entered into the database as
Bob's special string
It's important to note that prepared statements don't use escaping at all. Prepared statements send the query in one set and the data in another, so MySQL doesn't need to escape it, since it knows that's the actual value to store.
You can read more about the process in the MySQL manual
https://dev.mysql.com/doc/refman/5.0/en/string-literals.html
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 7 years ago.
I've done some searching here and have not found what I'm looking for.
I've got a form that gets filled out, upon submitting it adds it to an SQL database (using PHP). However, if someone puts an apostrophe or single quote, it will blow up...I need to be able to either parse each text field to check for single quotes to escape them out or find some other way for this to work. Here is my SQL statement...if it helps.
$query = "INSERT INTO workshopinfo (Year, Presentername, email, bio, arrival, title, description, costyn, matcost, schedlimit, additionalinfo, typeofws, verified)" .
"VALUES ('$year', '$presentername', '$email', '$bio', '$arrival', '$title', '$description', '$costyn', '$matcost', '$schedlimit', '$additionalinfo', '$typeofws', '$verified')";
So of course a single quote will blow it up, as will a double quote...it fails every time. There is likely an easy solution to this.
I may have just found it after posting. The php functon addslashes() works in this case.
You can use PDO with prepared statements to handle quotes in SQL requests :
$req = $bdd->prepare("INSERT INTO yourTable (a, b, c) VALUES (:a, :myb, :c)");
$req->bindParam("a", $name, PDO::PARAM_STR); // string
$req->bindParam("myb", $title, PDO::PARAM_STR); // string
$req->bindParam("c", $identifier, PDO::PARAM_INT); // integer
$req->execute();
With this, you avoid all SQL injections.
Documentation : http://php.net/manual/en/book.pdo.php
I am trying to avoid SQL injection in my page.
// Connect to database server and select database
$connection = new PDO("mysql:dbname=tt8888;host=mysql.tt8888.com", "tt8888", "ttnopassword");
// Quote data to prevent SQL injection
$name = $connection->quote($name);
// Insert now
$connection->query("INSERT INTO Contact (name, eeeee, llll, mmmmm, iiiii) VALUES ('$name','$eeeee','$llll','$mmmmm','$iiiii');");
Without quote(), it inserts just fine. And using print $name;, the quote() part seems work fine. Why is there nothing inserted into database after using quote()?
PDO::quote will put single quotes around your values. So you don't need to do that yourself in your SQL.
Though I'd strongly recommend you switch to using prepare() with named parameters.
Do not use PDO::quote. It is much better to use parameterized queries.
$stmt = $connection->prepare("INSERT INTO Contact (name, e, l, m, i) VALUES (?,
?, ?, ?, ?)");
// This will quote all of the values for you
$stmt->execute(array($name, $eeeee, $llll, $mmmm, $iiiii));
You can also use bind methods (bindParam or bindValue) instead of passing the arguments directly to execute. This will allow you to specify the data types if it's necessary, but it seems like these are all supposed to be strings.