MySQL Escaping Single Quotes With mysqli_real_escape_string - php

When I am inserting into a database with mysqli_real_escape_string, I am finding that my single quotes are been escaped with \\ rather than \ which is causing my query to fail. See below:
NOTE: $link is my db connection var.
$string = mysqli_real_escape_string($link, "BEGIN testing quotes - don't use quotes END");
$query = "INSERT INTO table (field) VALUES ('".$string."')";
When I echo out my query, I get:
INSERT INTO table (field) VALUES ('BEGIN testing quotes - don\\'t use quotes END')
which is causing a SQL syntax error. I cannot seem to find a setting anywhere that can change this. If I copy the echo'd query into MySQL workbench and remove a \, the query insert's perfectly.
I have had a look through Stack Overflow and cannot find anything relating to this, and also searched through Google with no luck.
I have many queries that need escaping across my entire website. Could a setting be set to automatically apply escaping of strings pre-insert without having to go through and update all my variables? If not, Is there anyway I can alter the mysqli_real_escape_string function without having to manually check every string I insert for single quotes etc?
I appreciate any assistance with this.

As Krishna Gupta suggested, stripslashes resolved my issue:
$string = mysqli_real_escape_string($link, stripslashes("BEGIN testing quotes - don't use quotes END"));
Thanks.

Related

PHP preg_replace() is returning null when string includes a single quote but works otherwise

The code below is very simple. PHP uses POST to collect a string from a form, which I am then looking to trim and run a preg_replace function which will strip any special characters except a single quote or a hyphen. Bare in mind that the entire code works fine without the involvement of the quotes or hyphen in the regex expression.
preg_replace("/[^\w\s'-]/", '', $raw_lemurName);
Those clean variables are then inserted into a database. Apache/2.4.37. MariaDB.
When I make lemurName a string like "Diademed Sifaka<>!", it works, and returns 'Diademed Sifaka'.
When I make it a string including a single quote, however, like "Coquerel's Sifaka" the operation doesn't complete and no information is inserted.
I have tested the regex expression on its own and it works fine, it seems that when you begin to involve SQL and databases that it ceases to work.
Worth noting:
using phpMyAdmin. If I insert the string on there it works fine so my database can hold those values.
Tried using mysqli_real_escape_string() in various places, but have had no luck, perhaps doing it wrong.
Reading around, I think it has something to do with SQL not allowing strings with single quotes being inserted and that the server automatically escapes single quotes in the post method.
Any ideas?
Much appreciated.
$raw_lemurName = isset($_POST['lemurName']) ? $_POST['lemurName'] : null;
$raw_lemurLat = isset($_POST['lemurLat']) ? $_POST['lemurLat'] : null;
$raw_family = isset($_POST['family']) ? $_POST['family'] : null;
//the regex expression below seems to be messing something up
$c_lemurName = trim(preg_replace("/[^\w\s'-]/", '', $raw_lemurName));
$c_lemurLat = strtolower(trim(preg_replace('/[^\w\s]/', '', $raw_lemurLat)));
$c_family = trim(preg_replace('/[^\w\s]/', '', $raw_family));
if (isset($_POST['submit'])) {
$query1 = "INSERT INTO `lemurs` (`id`, `lemur`, `latin`, `family`) VALUES (NULL, '$c_lemurName','$c_lemurLat','$c_family')";
$run_query = mysqli_query($connection, $query1);
if($run_query){
echo "Data has been inserted";
} else {
echo "Operation Unsuccessful";
}
header("location: index.php");
return;
}
This is a standard SQL injection problem. The issue stems from the way you are getting these variables into your query:
$query1 = "INSERT INTO `lemurs` (`id`, `lemur`, `latin`, `family`) VALUES (NULL, '$c_lemurName','$c_lemurLat','$c_family')";
Think about exactly what is happening here, all you are doing is concatonating strings together, so if $c_lemurName is ' - then your SQL will become:
[...] VALUES (NULL, ''', '[...]
This actually really opens you up to what is called an "injection attack". Basically, a malicious user could set $c_family to something like... ');drop table lemurs;-- - you are now executing an insert statement, and then a drop table statement, with the rest of your SQL being a comment.
There are several ways to combat this, the most frequently advised way is to look into paramaterised queries - which for the mysqli library have to be done through prepared statements. There's an example of this on the PHP docs page.
replace the single quotation marks from 2nd params area as well. use this.
preg_replace("/[^\w\s'-]/", "", $raw_lemurName);
hope it will work

How to properly add apostrophes into a mySQL INSERT command

I am trying to add some data into a MySQL database using a text area. However, when someone adds in an apostrophe it breaks the INSERT command because it acts as a single quote. How can this be fixed?
Here is what the command would look like if you stipped out all the variables that I am using.
INSERT INTO skills09 (name, birthday, skills) VALUES ('Tom Haverford', '31_02_1987', 'Being Awesome, Announcing cool things, Treatin' Yo Self, Failing');
As I was looking at this I had a thought.
Is it as simple as using double quotes around my variable names rather than single quotes? This seems like an easy fix but I have always used single quotes in MySQL.
you can escape the ' with a preceding '
INSERT INTO skills09 (name, birthday, skills) VALUES ('Tom Haverford', '31_02_1987', 'Being Awesome, Announcing cool things, Treatin'' Yo Self, Failing');
it's basically a dupe of
How do I escape a single quote in SQL Server?
if you gave more information on the language you're using or exactly how this sql statement is being formed by the users, I could give more information. for example, you would basically run the user's input through a function that would replace ' with '' (2 single quotes) right before sending it to the sql server.. in the sql server it will be correctly stored as just '
"escaping" the character is just a way for it to not count as the ending single quote, and allows it to be added in the insert.
PHP How to replace customers text area apostrophes with a escape character
$lastname = "O'Reilly";
$_lastname = mysqli_real_escape_string($lastname);
$query = "SELECT * FROM actors WHERE last_name = '$_lastname'";

Php to MsSql query - escape quotes (') issue

I'm building my query:
$q = sprintf("UPDATE testTable SET Text='%s', [Read]=0, TimeUpdated='%s', [From]='%s' WHERE ID='%s'", ms_escape_string($text), $dateReceived, $from, $convID);
and I execute it:
$res = mssql_query($q, $dbhandle);
$text should be free text so it could contain all sorts of weird characters (for now let's stick to ASCII). The simplest scenario is when $text contains a quote, e.g. $text = "Mc'Donalds"
Inside the ms_escape_string function I try to prevent this by replacing ' with 2 quotes ''.
I echo the query string:
UPDATE testTable SET Text='Mc''Donalds', [Read]=0, TimeUpdated='2012-08-03 12:44:49', [From]='bogus' WHERE ID='14'
(Note: executing this query from the VS server explorer on the same db works just fine)
Everything seems ok - see the double quotes for Mc''Donalds - but it still fails when executing: [mssql_query(): message: Incorrect syntax near 'Mc'
I thought that SET QUOTED_IDENTIFIER might be the culprit so I tried
$q = "SET QUOTED_IDENTIFIER OFF";
$resq = mssql_query($q,$dbhandle);
before executing my query but no cigar - I still get the same error.
Now I'm stuck - what should I change to get strings containing single quotes to pass through?
This question seems more to do with the lack of a native mssql_real_escape_string() function, which is addressed by this thread.
You should be more worried about an SQL injection attack, a problem many of us have finally put to bed by preferring to use PDO, as has been mentioned in the comments.
This type of "Escaping in readiness for the next recipient of the data" forms part of the FIEO mantra (Filter Input Escape Output).

Querying NON-escaped strings in MySQL

The table has company names which are not escaped.
My qry looks like
$sql = "SELECT id FROM contact_supplier WHERE name = '$addy' LIMIT 1";
The problem comes in where the company name values in the table are sometimes things like "Acme Int'l S/L".
(FYI: values of the $addy match the DB)
Clearly, the values were not escaped when stored.
How do I find my matches?
[EDIT]
Ahah!
I think I'm we're on to something.
The source of the $addy value is a file
$addresses = file('files/addresses.csv');
I then do a
foreach ($addresses as $addy) {}
Well, when I escape the $addy string, it's escaping the new line chars and including "\r\n" to the end of the comparison string.
Unless someone suggests a more graceful way, I guess I'll prob strip those with a str_replace().
:)
[\EDIT]
Why do you think the data already stored in the table should be escaped?
You should escape data only right before it is written directly into a text-based language, e.g. as a part of an SQL query, or into an HTML page, or in a JavaScript code block.
When the query is executed, there's nothing espaced. MySQL transforms it and inserts, otherwise it wouldn't insert and gives error because of syntax or we escape them for security like sql injection.
So your query with escaped values will be working fine with the data in your database.
If the values were not escaped when stored then they would have caused SQL errors when you tried to enter them.
The problem is that the data is not being escaped when you make the query.
Quick hack: Use mysql_real_escape_string
Proper solution: Don't build SQL by mashing together strings. Use prepared statements and parameterized queries
Another option would be to change your query to this...
$sql = "SELECT id FROM contact_supplier WHERE name = \"$addy\" LIMIT 1";
Use mysql_real_escape_string:
$addy = mysql_real_escape_string($addy);
Or try using parameterized queries (PDO).
Regarding this statement:
Clearly, the values were not escaped when stored.
This is incorrect logic. If the values weren't escaped in the original INSERT statement, the statement would have failed. Without escaping you'd get an error along the lines of syntax error near "l S/L' LIMIT 1". The fact that the data is correctly stored in the database proves that whoever inserted it managed to do it correctly (either by escaping or by using parameterized queries).
If you are doing things correctly then the data should not stored in the database in the escaped form.
The issue turned out to be new-line characters
The source of the $addy value starts out like this
$addresses = file('files/addresses.csv');
I then goes through
foreach ($addresses as $addy) {}
When I escape the $addy string, it's escaping the new line chars and inserting "\r\n" on the end of the comparison string.
As soon as I dropped those chars with string_replace() after escaping, everything went swimmingly
Thanks-a-BUNCH for the help

Why does my mysql_real_escape_string not work?

I have read many about SQL-Injection. But it does not work with this code:
$inputform= $_GET["password"];
$query = "INSERT INTO user(password) VALUES ('".mysql_real_escape_string($inputform)."')";
For example I use this example: O'Conner. When I submit it and look in my table there is O'Connor and not O\'Conner.
thanks
The quote is escaped so that MySQL doesn't interpret it as a string delimiter. The backslash doesn't get stored in the database, and it's not supposed to either. What you're seeing is the correct, expected and documented behaviour.
The best solution, BTW, is to use PDO and parametrized queries.
mysql_real_escape_string() escapes the value so that the SQL parser for MySQL can interpret the value correctly when it stores the value, it is not actually stored in the database as an escaped string
If you get O'Connor in your table, it's working properly. But try echo $query and you'll see the results of the escaping.
It works just fine! There shouldn't be "O\'Conner" in your database, just in the query. If it didn't work, your query wouldn't succeed, because the ' in O'Conner would ruin your query.
When you look in the table, it should be O'Connor - that means the string was escaped properly in the SQL. If it hadn't been escaped by mysql_real_escape_string, you probably would have ended up with a syntax error.
The query would end up as:
INSERT INTO user(password) VALUES ('O'Connor)
If you want the backslashes in the DB, try using addslashes before you pass it to mysql_real_escape_string, but you probably don't.

Categories