Why does msyqli_real_escape_string() not escape multiple backslashes properly? - php

Given this SQL
UPDATE `mytable`
SET `mycolumn`='karla bailey-pearapppppppp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
WHERE `id`=5619
Why will mysqli_real_escape_string() not escape this string properly?
Trying to use this SQL query after escaping the column's value produces this mysqli error:
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''karla bailey-pearapppppppp\\\\\\\\\\\\\\\\\\\\\\\\\\\' at line 3"
Is there a limit to the number of backslashes that can be escaped?

Are you escaping the ENTIRE string? e.g.
$sql = "UPDATE .... \\\\\\\'";
$escaped = mysqli_real_escape_string($link, $sql);
If so, that's incorrect. You are trashing the string by doing that. You'll also be escaping the ' that delimit your where clause value. Escaping should be performed only VALUES that you're inserting into the string. e.g.
$name = "Miles O'Brien"; // ' in name would cause syntax error
$bad_sql = "SELECT '$name'";
$broken_sql = mysqli_real_escape_string($link, $bad_sql);
// produces: SELECT \'Miles O\'Brien\'
$ok_sql = "SELECT '" . mysqli_real_escape_string($link, $name) . "'";
// produces: SELECT 'Miles O\'Brien';

Ok, so I found the problem. The application checks for the value length > column maximum, and if the value is too great, truncates the value AFTER the escape is done - thereby breaking the escaped value (very isolated case where this would occur, this code has been in place for years).
Ergo, can't truncate a value that ends in backslashes after the value is already escaped.

Related

Strip Out All Unwanted Characters

I am using the following code to strip out unwanted characters but it is not stripping out everything and throwing a MySQL error:
$commentmessage = strip_tags($commentmessage);
$commentmessage = htmlentities($commentmessage, ENT_QUOTES);
What code would I use to strip out anything that might cause a MySQL error?
The message I am receiving is:
Error message: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'omg thats the one". One of the logo's we really liked was 1049859 where the f' at line 2**
Evidently you're building your query like so:
$query = "INSERT INTO foo VALUES ('$bar')";
which is breaking because the text of $bar contains single quotes. '
No. *hits you with a rolled-up newspaper* Bad developer.
I could just throw you a string escaping function, or I could show you to do it right like:
$bar = "I am a problematic string!'; DROP TABLE USERS -- "
$query = "INSERT INTO foo VALUES (?)";
$stmt = $dbh->prepare($query);
$stmt->execute(array($bar));
Or:
$bar = "I am a problematic string!'; DROP TABLE USERS -- "
$query = "INSERT INTO foo VALUES (:bar)";
$stmt = $dbh->prepare($query);
$stmt->execute(array('bar'=>$bar));
When you prepare a query like this PHP/PDO/MySQL get together and pre-agree on what types your placeholders are. So your strings are treated like strings without the need for escaping characters. This both prevents rogue single quotes from breaking your query, and help protect you from SQL injection attacks.
You can also re-use prepared statements to increase performance: [relative to un-prepared statements since the SQL only needs to be parsed once, rather than once per query]
$query = "INSERT INTO foo VALUES (?)";
$stmt = $dbh->prepare($query);
foreach( $bars as $bar ) {
$stmt->execute(array($bar));
}

Escaping a single quote in a variable before Insert

Here's how my insert code looks:
$values .= ($ta->account_toll_free_number != '') ? ",('" . $post_id . "', 'toll_free_number','" . $ta->account_toll_free_number . "')" : NULL;
Which gives me:
(111, 'toll_free_number', '888-123-1234')
Which works great until there is a single quote mark in the variable. Then it breaks. Is there someway I can clean/escape it before this? Do I just need to swap my single quotes to double quotes?
I did it this way.
I just started with your output and added a single quote for last part.
$values = mysql_real_escape_string("(111, 'toll_free_number', '888-'123-1234')");
$query = "INSERT INTO yourtable (fieldname) values ('".$values."')";
mysql_query($query) or die(mysql_error());
see more from manual http://php.net/manual/en/function.mysql-real-escape-string.php
As the commenter pointed out, I would recommend you use PDO as this is an escaping issue and opens you up to SQL injection vulnerabilities. On the change that you are using mysql_* instead, try escaping the variable with mysql_real_escape_string() first.

unable to encode url in mysql php insert

I am trying to insert a url to mysql(through php) column but unable to do it.
I am getting the following error
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%2F%2Flocalhost%2Fclient%2Fsave_file.php%3Ffilename%3D9 WHERE queryid='29'' at line 1
The code snippet :
$_POST['url1']="//localhost/client/save_file.php?filename=9";
$_POST['query_id']=29;
$var=$_POST['url1'];
$query_id=$_POST['query_id'];
// echo "$var";
$var=rawurlencode($var);
//echo "$var";
$sql1 = "UPDATE query_audio SET query_content=$var WHERE queryid='".$query_id."' ";
if (!mysql_query($sql1)) {
die('Error: ' . mysql_error($connection));
}
You have a fundamental misunderstanding of how to defend against SQL injection attacks You need to use mysql_real_escape_string(), not urlencode().
Plus, you forgot to quote your $var variable, so your query is litterally:
... SET query_content=http:%2F%2Fetc...
Without quotes around that url, mysql is free to interpret the http: portion as an (invalid) field name.
Try
$var = mysql_real_escape_string($_POST['url1']);
$query_id = mysql_real_escape_string($_POSt['query_id']);
$sql = "UDPATE ... SET query_content='$var' WHERE queryid='$query_id';";
^----^-- note these quotes.

SQL Query Error Near ''

UPDATE ".$tablename." SET stock=%s WHERE itemname=".$itemname."
SQL Query throwing this error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '' at line 1
Can't find what it is talking about as it only gives me '' and not any text in the query. Thanks!
The string concatenation above looks really messy!
I would go for something simple:
$sql = "UPDATE $tablename SET stock='$stock' WHERE itemname='$itemname'";
If this doesn't work, you should debug the values of : $tablename, $stock and $itemname
ps. I've already given +1 to Nick :)
The example looking incomplete.
Is it possible that variables $tablename or $itemname to be empty?
you are mixing sprintf and string concatenation. The best way is to use the only one method. i.e.:
$sql = "UPDATE %s SET stock='%s' WHERE itemname='%s'";
sprintf($sql, $tablename, $stock, $itemname); //use this in mysql_query
But agree with Parker that you don't quote your string
Try, it doesn't look like you're quoting your strings.
UPDATE ".$tablename." SET stock='%s' WHERE itemname='".$itemname."'

Problem with MYSQL database, values are not inserted

I am trying to insert values in database and values are not being inserted, here is the code i have:
$user_name = "username";
$password = "password";
$database = "database";
$server = "localhost";
$db_handle = mysql_connect($server, $user_name, $password);
$db_found = mysql_select_db($database, $db_handle);
if ($db_found) {
$SQL = 'INSERT INTO table (anInt, DomainName, URL, Rank, PageRank, Google, Bing, Boss, IndexedPage, Backlinks) VALUES ($anInt, $Domain, $URL, $Rank, $Pagerank, $Google, $Bing, $Yahoo, $Pages, $backlinks)';
$result = mysql_query($SQL);
mysql_close($db_handle);
print "Records added to the database";
it is printing that records added to the database but when looking at the database nothing is being added. some of the values are doubles, text, and ints. Is there anyway to debug this? I will be adding more information to the post if someone asks me to.
and of course I have an else statement i just thought it is not relevant since it is telling me that records are added.
First of all, you should escape the string values you are passing into the SQL query, using mysql_real_escape_string.
Then, you should add quotes, in your SQL query, arround the fields that are meant to contain strings.
I don't really know which fields are integers and which fields are strings, but you should be using something like this to build your SQL query :
// Escape the string data, and make sure integer really contain integers
$anInt = intval($anInt);
$Domain = mysql_real_escape_string($Domain);
$URL = mysql_real_escape_string($URL);
$Rank = intval($Rank);
$Pagerank = = intval($Pagerank);
$Google = intval($Google);
$Bing = intval($Bing);
$Yahoo = intval($Yahoo);
$Pages = intval($Pages);
$backlinks = intval($backlinks );
// Build the SQL query, using the "safe" variables
$SQL = 'INSERT INTO table (anInt, DomainName, URL, Rank, PageRank, Google, Bing, Boss, IndexedPage, Backlinks)
VALUES ($anInt, '$Domain', '$URL', $Rank, $Pagerank, $Google, $Bing, $Yahoo, $Pages, $backlinks)';
This is supposing that only DomainName and URL are meant to contain strings -- you might have to use mysql_real_escape_string and add quotes arround the values for some other fields too, if needed.
Then, you should take a look at the return value of mysql_query : for an insert query, in case of an error, it'll return false.
Here, if your $result variable is false, you should use mysql_error and mysql_errno : they'll allow you to know what error happened -- it will help detecting errors in your SQL query, for instance.
If this doesn't solve the problem, you should try outputting the SQL query, and run it using something like phpMyAdmin, to make sure it's OK.
I am no PHP expert, but I have 2 remarks.
You don't check the error (perhaps with mysql_errno()) so you don't know whether the records were added
I think the values, if they are strings, should be given like
'$Domain'
that is, escaped with ' characters.
better would be, of course, using something like
$sql = sprintf("INSERT ... VALUES(%d, '%s', '%s',...)",
$anInt, mysql_real_escape_string($Domain), ...);
if you insert user-supplied input.
You could examine the $result:
$result = mysql_query($query);
if (!$result) {
print "An error occured: " . mysql_error() . "\n";
}
My guess is that you're passing a string without quotes, like:
VALUES (Hello)
where you should pass it like:
VALUES ('Hello')
Like the commenter said, if the user can control these strings, you are open to an SQL Injection attack. You can prevent that attack by escaping the strings, for example:
$query = sprintf("INSERT INTO table (DomainName) VALUES ('%s')",
mysql_real_escape_string($domain_name));
In SQL queries, you need to enquote strings correctly, or it will produce an error. So all your variables that are used to store non-int or non-boolean values in the database need quotes around the values.
Additionally you should make sure that SQL injections are not a problem by escaping all values with mysql_real_escape_string first.
Apart from sql injections your error handling is not complete...
if (!$db_found) {
echo "datbase not found.";
}
else {
$SQL = 'INSERT INTO
table
(...)
VALUES
(...)
';
$result = mysql_query($SQL, $db_handle);
if ( !$result ) {
echo "error: ", mysql_error($db_handle);
}
else {
print "Records added to the database";
}
}
mysql_close($db_handle);
In case a query causes an error mysql_query() return FALSE and mysql_error() will tell you more about the error.
Well there are security issues with the code but to address one problem
you are not enclosing your string values in quotes in the SQL statement.
First of all, please regard everybody else's advice on safe database handling and avoiding injection.
The reason your query isn't doing anything is probably that you enclosed the string in single quotes. In PHP single quotes enforce the string to be literal. Unlike when using double quotes, variables will NOT be substituted. So '$foo' represents the sequence of characters '$'.'f'.'o'.'o'. "$foo" on the other hand represents the sequence of characters of whatever the variable $foo contains at the time of the string's definition.
You can use mysql_error() to catch most problems with MySQL. Even if the message isn't helping you, you at least know whether the query was parsed properly, i.e. on which end of the connection the problem lies.

Categories