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
Related
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 7 years ago.
I have a perplexing issue that I can't seem to comprehend...
I have two SQL statements:
The first enters information from a form into the database.
The second takes data from the database entered above, sends an email, and then logs the details of the transaction
The problem is that it appears that a single quote is triggering a MySQL error on the second entry only! The first instance works without issue, but the second instance triggers the mysql_error().
Does the data from a form get handled differently from the data captured in a form?
Query 1 - This works without issue (and without escaping the single quote)
$result = mysql_query("INSERT INTO job_log
(order_id, supplier_id, category_id, service_id, qty_ordered, customer_id, user_id, salesperson_ref, booking_ref, booking_name, address, suburb, postcode, state_id, region_id, email, phone, phone2, mobile, delivery_date, stock_taken, special_instructions, cost_price, cost_price_gst, sell_price, sell_price_gst, ext_sell_price, retail_customer, created, modified, log_status_id)
VALUES
('$order_id', '$supplier_id', '$category_id', '{$value['id']}', '{$value['qty']}', '$customer_id', '$user_id', '$salesperson_ref', '$booking_ref', '$booking_name', '$address', '$suburb', '$postcode', '$state_id', '$region_id', '$email', '$phone', '$phone2', '$mobile', STR_TO_DATE('$delivery_date', '%d/%m/%Y'), '$stock_taken', '$special_instructions', '$cost_price', '$cost_price_gst', '$sell_price', '$sell_price_gst', '$ext_sell_price', '$retail_customer', '".date('Y-m-d H:i:s', time())."', '".date('Y-m-d H:i:s', time())."', '1')");
Query 2 - This fails when entering a name with a single quote (for example, O'Brien)
$query = mysql_query("INSERT INTO message_log
(order_id, timestamp, message_type, email_from, supplier_id, primary_contact, secondary_contact, subject, message_content, status)
VALUES
('$order_id', '".date('Y-m-d H:i:s', time())."', '$email', '$from', '$row->supplier_id', '$row->primary_email' ,'$row->secondary_email', '$subject', '$message_content', '1')");
You should be escaping each of these strings (in both snippets) with mysql_real_escape_string().
http://us3.php.net/mysql-real-escape-string
The reason your two queries are behaving differently is likely because you have magic_quotes_gpc turned on (which you should know is a bad idea). This means that strings gathered from $_GET, $_POST and $_COOKIES are escaped for you (i.e., "O'Brien" -> "O\'Brien").
Once you store the data, and subsequently retrieve it again, the string you get back from the database will not be automatically escaped for you. You'll get back "O'Brien". So, you will need to pass it through mysql_real_escape_string().
For anyone finding this solution in 2015 and moving forward...
The mysql_real_escape_string() function is deprecated as of PHP 5.5.0.
See: php.net
Warning
This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include:
mysqli_real_escape_string()
PDO::quote()
You should do something like this to help you debug
$sql = "insert into blah values ('$myVar')";
echo $sql;
You will probably find that the single quote is escaped with a backslash in the working query. This might have been done automatically by PHP via the magic_quotes_gpc setting, or maybe you did it yourself in some other part of the code (addslashes and stripslashes might be functions to look for).
See Magic Quotes
You have a couple of things fighting in your strings.
lack of correct MySQL quoting (mysql_real_escape_string())
potential automatic 'magic quote' -- check your gpc_magic_quotes setting
embedded string variables, which means you have to know how PHP correctly finds variables
It's also possible that the single-quoted value is not present in the parameters to the first query. Your example is a proper name, after all, and only the second query seems to be dealing with names.
You can do the following which escapes both PHP and MySQL.
<?
$text = '';
?>
This will reflect MySQL as
How does it work?
We know that both PHP and MySQL apostrophes can be escaped with backslash and then apostrophe.
\'
Because we are using PHP to insert into MySQL, we need PHP to still write the backslash to MySQL so it too can escape it.
So we use the PHP escape character of backslash-backslash together with backslash-apostrophe to achieve this.
\\\'
You should just pass the variable (or data) inside "mysql_real_escape_string(trim($val))"
where $val is the data which is troubling you.
I had the same problem and I solved it like this:
$text = str_replace("'", "\'", $YourContent);
There is probably a better way to do this, but it worked for me and it should work for you too.
mysql_real_escape_string() or str_replace() function will help you to solve your problem.
http://phptutorial.co.in/php-echo-print/
This question already has answers here:
PHP - 500 instead of error
(2 answers)
Can I mix MySQL APIs in PHP?
(4 answers)
Why shouldn't I use mysql_* functions in PHP?
(14 answers)
How can I prevent SQL injection in PHP?
(27 answers)
Closed 5 years ago.
In my webpage, I ask a user to fill out a form specifying their age, race, gender, and state. Upon submission, the data is submitted to the same page and the page will process it with the following code to submit it to a database (all database login info is faked in this example):
<?php
if($_COOKIE['infoGiven']==true){
$con=mysql_connect('localhost','asasdfasd','asdf','asdfasdf');
if($_COOKIE['like']==true){
$sql="INSERT INTO LIKE(state, age, gender, race)
VALUES(\'".$_POST["state"]."\'".$_POST["age"]."\'".$_POST["gender"]."\'".$_POST["race"].")";
$con->query($sql);
}
if($_COOKIE['like']!=true){
$sql="INSERT INTO DISLIKE(state, age, gender, race)
VALUES(\'".$_POST["state"]."\'".$_POST["age"]."\'".$_POST["gender"]."\'".$_POST["race"].")";
$con->query($sql);
}
}
?>
This should simply submit the user data to the database, but instead I receive a blank page with a "500" error. There is no code inside the . Keep in mind that, prior to form submission, the page renders properly.
You're missing the commas in your insert statement; you also don't have to escape single quotes when you're utilizing double quotes.
As your code is right now, you're trying to insert one really concatenated string.
$sql="INSERT INTO LIKE(state, age, gender, race)
VALUES(\'".$_POST["state"]."\'".$_POST["age"]."\'".$_POST["gender"]."\'".$_POST["race"].")";
Should be:
$sql="INSERT INTO `LIKE`(state, age, gender, race)
VALUES('".$_POST["state"]."', '".$_POST["age"]."', '".$_POST["gender"]."', '".$_POST["race"]."')";
But that's to illustrate the punctuation issues with the parameters: don't use that code itself, because the alternatives are more secure and less deprecated.
Better version using mysqli prepared statements:
$db = new mysqli("DBHOST","DBUSERNAME","DBPASS","DBNAME");
$stmt = $db->prepare("INSERT INTO `LIKE`(state, age, gender, race) VALUES (?,?,?,?)");
$stmt->bind_param('i', $VALUE)
^ bind parameters like this. The first parameter is the type of the second parameter (integer in this case, 's' for string, etcetera). $VALUE is the variable to bind. The number of parameters bound has to match the numbers of placeholders/question marks; this prepared statement expects four.
To bind multiple parameters in one line, you can use the format bind_param('sss', $string1, $string2, $string3), to pick an example. Then:
$stmt->execute();
$stmt->close();
I'd also check your connection object to make sure it's successfully connecting to the database with the actual login information. Along with that, don't forget to sanitize/validate your input before it goes into the database. This covers it well.
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 6 years ago.
$type_of_poker = "hold'em no limit";
$sql = "INSERT INTO hands (type_of_poker) VALUES ('$type_of_poker')";
Im trying to put hold'em no limit into a SQL database but it won't let me
use ' i cant upload holdem no limit for a long list resones that have to do
with the rest of my code.
Instead of trying to escape the apostrophe, it is much better practice to use prepared statements and binded parameters which will also solve your problem. It solves your problem because you then don't need to escape the apostrophe ('):
$type_of_poker = "hold'em no limit";
//binding the parameters to your sql statement
$sql = "INSERT INTO hands (type_of_poker) VALUES (:type_of_poker)";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':type_of_poker',$type_of_poker);
$stmt->execute();
Let me know if that worked for you! :)
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.
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);