MySQL update/insert strips backslashes for unicode entries - php

I'm trying to insert/update a SQL field with JSON data that encodes unicode as \u, but it's stripping it out:
"Sauteéd -> ["Saute\u00e9d"]
However, it's being saved in the database like this:
["Sauteu00e9d"]
I've tried countless preg_replace and str_replace methods, but none of them work. Is there something I can do about this - it's driving me mad.
Thanks!

Use mysql_real_escape_string if you aren't.

My guess is that you use PHP
In that case you should use mysql_real_escape string instead of preg replace.
It's easier and much better against SQL injections.

mysql_real_escape_string is obviously now deprecated so here is how you would do it in modern PHP:
$value = $mysql_conn->real_escape_string("Saute\u00e9d");
$query = "update so_and_so set param = '$value' where var1 = 'somevalue'";
...
...
or however you happen to run your queries...

Related

PHP & MySql query with apostrophes

I have the following php version:
PHP Version 5.3.2-1ubuntu4.19
and this php string:
$l_sDesc = "It doesn' t contain any dangerous substances";
If i try to make a query with db_query (Drupal) i get an error due to the apostrophe;
db_query("UPDATE mytable SET description= '$l_sDesc' where id = $id");
I've tried to use mysql_real_escape_string() but i get an empty string:
$l_sDesc = mysql_real_escape_string($l_sDesc); //i have an empty string as result
What's the problem?
Drupal use another DB Wrapper. Normally you can create prepared statements.
https://api.drupal.org/api/drupal/includes!database!database.inc/group/database/7
Here is a correct example. If you use the correct prepared statements your input will be filtered.
Otherwise use stripslashes().
http://php.net/manual/de/function.stripslashes.php
Tom, you need to "prepare" the string for SQL before you actually run the statement.
Try the PHP function mysql_real_escape_string on your strings before you actually use them.
http://php.net/manual/en/function.mysql-real-escape-string.php
I suggest to use $l_sDesc = htmlspecialchars($l_sDesc);

mysql_real_escape_string not escaping all types of ”

I noticed something weird with mysql_real_escape_string function. It does not escape“ or ”, for example:“TEST” is not converted into \“TEST\”.
The functions work fine with " (look closely and you see they are different)
Any idea how to fix this, I rather not write this function from scratch. Is it deprecated, is there an alternative?
EDIT: Thank you all for answering. To clarify I am trying to insert this string Things I Like” catalog \r\n into a DB, and for some reason it is not working. Everything is works fine for any other string, and I am not getting any error message, it's just not appearing in the DB. So I thought it might be related to ”.
Go easy on me guy!
EDIT2
$interestTable = "5431591 1 Things I Like” <br>";
//problem lies here
$count = 0;
$interestTable = preg_replace_callback( '/<br>/', function( $match) use( $tagName, &$count) {
return $tagName[$count++][0] . ' ' . PHP_EOL;
}, $interestTable);
//$interestTable = "5431591 1 Things I Like” catalog \r\n" after format
$interestTable = mysql_real_escape_string($interestTable);
echo $interestTable;
mysql_query("INSERT INTO $tbl_name(userID,storyID,rank, storyType, interestTable)VALUES('$userID','$storyID','$rank','$storyType','$interestTable')", $dbh1);
EDIT3 I was not mistaken, I changed the string from Things I Like” catalog \r\n to Things I AA catalog \r\n and it worked. I have no idea why this happens, maybe something gets messed up with the encoding after converting to a string but I am not sure. All I know for sure that after removing ” from the string, everything works fine
Yup. Never rely on black-listing mechanisms like that for safety. It's broken, and can result in some interesting SQL injections:
$query = "SELECT id, title, body FROM posts WHERE id = " . mysql_real_escape_string($_GET['id']);
This can still be injected:
1 OR 1=1
Resulting in:
SELECT id, title, body FROM posts WHERE id = 1 OR 1=1
All results are returned. Not convinced this is bad? Ok...
1 OR 1=1 UNION SELECT id, username, password FROM users
Whoops!
Why is this injectable? The developer just forgot to quote the numeric ID. If you can ever see yourself making this mistake, you should seek a better solution.
My advice? Stop using string concatenation, stop using the deprecated mysql_ functions, and shift to MySQLi or PDO with parameterised queries, where content is explicitly separated from query language.
Curly quotes don't need to be escaped, as they have no special meaning to MySQL.
That's because "smart" quotes are not recognised as quotes by the MySQL engine, and therefore pose absolutely no risk of injection attacks.
You don't need to escape “ or ”. There is nothing to fix.
The mysql_ functions are no longer maintained and are deprecated as of PHP 5.5.0
You don't however need to escape “ or ”. These aren't recognised by MySQL as quotes.
I would suggest you use the PDO or MySQLi extension's when connecting to a MySQL database.
As I thought, it turns out to be an encounding problem.
After using utf8_encode (http://php.net/manual/en/function.utf8-encode.php) on my string everything worked fine.
Thank you all for you help (especially Polynomial).

Problems with mysql insert

My php script won't work if i try to insert into database something in Saxon genitive (for example value "mike's" won't be inserted).
PHP code is plain and simple:
"INSERT INTO cache (id,name,LinkID,number,TChecked) VALUES(".$idUser.",'".$LinkName."',".$LinkID.",".$number.",NOW());"
Everything works great until "$LinkaName" get some value with "special character". How to put values like "mike's", "won't" etc. into MySql database?
You need to escape these strings properly. In addition, the technique that you're using right now exposes you to an SQL injection attack.
The PHP docs for mysql_real_escape_string gives a good example of what you should do:
// Query
$query = sprintf("INSERT INTO cache (id,name,LinkID,number,TChecked) VALUES(%d,'%s',%d,%d,'%s');",
mysql_real_escape_string($idUser),
mysql_real_escape_string($LinkName),
mysql_real_escape_string($LinkID),
mysql_real_escape_string($number),
mysql_real_escape_string(NOW()));
You must escape them first, otherwise you generate an invalid query. The single quote matches the single quote at the start of the string.
$LinkName = mysql_real_escape_string($LinkName);
You can also use prepared statements to bind parameters to the query instead of concatenating and sending a string (use the PDO or mysqli libraries instead of the mysql lib).
You need to use mysql_real_escape_string() on those values.
Also make sure if you are not quoting those other variables, to cast them to integer (the only reason why you wouldn't quote them).
If you're using mysqli or PDO and not the standard extension, you can use a prepared statement instead of escaping.

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.

Is this query vulnerable to sql injection?

$myq = sprintf("select user from table where user='%s'", $_POST["user"]);
I would like to know if the above query can be exploited using SQL injection. Is there any advanced SQL injection technique that could break sprintf for this particular query?
I don't think it needs to be particularly advanced... try an input of
' OR 1 = 1 OR user='
In other words, you'll get SQL of:
select user from table where user='' OR 1 = 1 OR user=''
Does that look like a query you really want to execute? (Now consider the possibility of it dropping tables instead, or something similar.)
The bottom line is that you should be using a parameterised query.
Yes, I'd say you have a potential problem there :)
You need to escape: \x00, \n, \r, \, ', " and \x1a. sprintf() does not do that, sprintf() does no modification to strings, it just expands whatever variadic arguments that you give it into the buffer that you provide according to the format that you specify.
If the strings ARE being transformed, its likely due to magic quotes (as Rob noted in Comments), not sprintf(). If that is the case, I highly recommend disabling them.
Using sprintf doesn’t give you any more protection than using simple string concatenation. The advantage of sprintf is just having it a little more readable than when to using simple PHP’s string concatenation. But sprintf doesn’t do any more than simple string concatenation when using the %s format:
$str = implode('', range("\x00", "\xFF")); // string of characters from 0x00 – 0xFF
var_dump(sprintf("'%s'", $str) === "'".$str."'"); // true
You need to use functions that escape the contextual special characters you want to insert your data into (in this case a string declaration in MySQL, supposing you’re using MySQL) like **mysql_real_escape_string** does:
$myq = sprintf("select user from table where user='%s'", mysql_real_escape_string($_POST["user"]));
when $_POST["user"] would equal "';SHUTDOWN;" - what would happen?
Actually, turn off magic quotes.
In PHP, where it's appropriate, use filters:
$inUser = $_POST['user'];
$outUser = filter_var($inUser, FILTER_SANITIZE_STRING);
Filters strip out HTML tags and escape various characters.
In addition, you can let your database escape it for you:
$inUser = $_POST['user'];
$outUser = mysqli_real_escape_string($conn, $inUser);
This escapes MySQL specific special characters like double quotes, single quotes, etc.
Finally, you should use parameterized queries:
$sql = "SELECT user FROM table WHERE user = ?";
$stmt = $pdo->prepare($sql);
$params = array($outUser);
$stmt->execute($params);
Parameterized queries automatically add the quotes around strings, etc., and have further restrictions that make SQL injections even more difficult.
I use all three, in that order.
Ahh here I come with the magic answer! :)
magic quotes do escaping for you!
So, you have to turn magic_quotes_gpc ini directive off
and then use mysql_real_escape_string as suggested.
Yes.
If somebody put in the following as the user in your form:
'; delete * from table
$_POST["user"] = "' or 1=1 or user='"

Categories