mysql_real_escape_string does not escape " - php

In PHP, I am escaping characters before insert in a MySQL database using mysql_real_escape_string
$array_to_insert = array_map('mysql_real_escape_string', $my_arr);
$mysql->setTbl("mytable");
$id = $mysql->insertArray($array_to_insert);
When saving, double quotes are being saved as escaped with a \. I do not want this, since some of the data is HTML and it may contain tags like <a href="www.stackoverflow.com"> etc, which will be saved as <a href=\"www.stackoverflow.com\"> and then displayed incorrectly in a WordPress setup.
I have read elsewhere on stackoverflow that to avoid escaping the double quotes, one must first insert (as above) then select and insert into a table again.
Is there a way to solve this issue without having to select and re-insert?
Thanks
(note: the database I am using is in utf-8 format)

Your server may have magic_quotes enabled. Check it with
var_dump( get_magic_quotes_gpc() );
Otherwise, it's probably something you are doing beforehand or that your db library is doing. mysql_real_escape_string only escapes the string so that it is safe to use in a SQL query. It can't help if the string is already escaped to begin with.

You could always strip slashes on the way out using http://php.net/manual/en/function.stripslashes.php
for instance:
$sql = "SELECT * FROM table_name";
$result = mysql_query($sql) or mysql_error();
while ($output = mysql_fetch_assoc($result)) {
echo stripslashes($output['column_name']);
}
alternatively, just remove all escaped double quotes:
echo str_replace('\"', '"', $output['column_name']);

Related

What is the point of PHP's stripslashes function?

Suppose you have the following:
<?php
$connection = mysqli_connect("host", "root", "passwd", "dbname");
$habits = mysqli_real_escape_string($connection, $_POST['habits']);
?>
Lets say you entered, for a field called 'habits', the value 'tug o' war'. Therefore, the mysqli_real_escape_string function will escape the second quote symbol and the database engine won't be fooled into thinking that the value is 'tug o'. Instead, it will know that the value is actually 'tug o' war'. My question is, why then do you need a stripslashes function? A stripslashes function will simply strip away the good work that was done by the mysqli_real_escape_string function. Stripping away a backslash will simply return you to where you were, and the database will be fooled again. Am I to assume that the stripslashes function is NOT used for database purposes? That is, would this piece of code be completely nonsensical?:
<?php
$connection = mysqli_connect("host", "root", "passwd", "dbname");
$habits = mysqli_real_escape_string($connection, $_POST['habits']);
$undosomething = stripslashes($habits);
echo '$undosomething';
?>
If stripslashes is NOT used for database purposes, what exactly is it used for?
(As of 2014) It still has it's uses. It's not really used with a database but even with this, there are use cases. Let's assume, or send data from form using JavaScript and you have a string with a quote such as "It's". Than getting the value through the $_GET supervariable, you'll get the value "It's". If you than use mysqli_real_escape_string() or similar (which you must use for security), the quote will be double encoded and the backslash will be saved to the DB. For such scenarios, you would use this function. But it is not for security and not necessarily used with a DB.
Per the Manual, the purpose of stripslashes() is to unquote a quoted string, meaning to remove a backslash quoting a character. Note, PHP lacks a character data type, so all single characters are strings. You may wish to peruse this example code which demonstrates that this function leaves forward slashes as well as escape sequences involving non-printable characters unaltered. Stripslashes() arose to counter excessive quoting caused by a feature that PHP formerly supported: magic quotes.
In the early days of PHP when Rasmus Lerdorf worked with databases that necessitated escaping the single quote character, he found a way to avoid the tedium of manually adding a backslash to quote or escape that character; he created magic quotes:
... useful when mSQL or Postgres95 support is enabled
since ... single quote has to be escaped when it is
part of [a] ... query ...
(See php.h in PHP/FI [php-2.0.1] )
While magic quotes saved developers from having to use addslashes(), this feature could automatically quote inappropriately. A form's input with a value of O'Reilly would display as O\'Reilly. Applying stripslashes() fixed that issue. Though stripslashes() lived up to its name and stripped away backslashes, it was inadequate for addressing all the problems associated with magic quotes, a feature that would ultimately be deprecated in PHP5.3 and then removed as of PHP5.4 (see Manual).
You may view quoted data if you are still using a version of PHP that supports magic quotes. For example, consider the case of a $_GET variable that originates from a JavaScript containing a url-encoded string, as follows:
location.href="next_page.php?name=O%27Riley"; // $_GET['name'] == O\'Riley
If you were to apply to $_GET['name'] either addslashes() or mysqli_real_escape_string(), this variable's value would expand, containing two more backslashes, as follows:
O\\\'Riley
Suppose the variable were next used in an insert query. Normally the backslash of a quoted character does not get stored in the database. But, in this case, the query would cause data to be stored as:
O\'Riley
The need for stripslashes() is much less likely nowadays, but it's good to still retain it. Consider the following JavaScript, containing a flagrant typo:
location.href="http://localhost/exp/mydog.php
?content=My%20dog%20doesn\\\\\\\\\\\\\%27t%20
like%20to%20stay%20indoors."
Using stripslashes(), one may dynamically correct the code as follows:
function removeslashes($string)
{
while( strpos( $string, "\\" ) !== FALSE ) {
$string = stripslashes( $string );
}
return $string;
}
$text = htmlentities($_GET['content']);
if (strpos($text,"\\") !== FALSE ) {
echo removeslashes( $text );
}
Note: stripslashes() is not recursive.
There is no point to stripslashes().
Some folks used to think this provided them security, but as you can see it does not. It should be removed from PHP completely, but it hasn't been.
addslashes():
w3schools.com - function returns a string with backslashes in front of predefined characters.
php.net - Quote string with slashes
stripslashes():
w3schools.com - function removes backslashes added by the addslashes() function.
php.net - Un-quotes a quoted string
<?php
$str = "Who's Peter Griffin?";
echo $str . " This is original string." . PHP_EOL;
echo addslashes($str) . " This is addslashes string." . PHP_EOL;
echo stripslashes(addslashes($str)) . " This is stripslashes string." . PHP_EOL;
?>
Embed PHP online:
body, html, iframe {
width: 100% ;
height: 100% ;
overflow: hidden ;
}
<iframe src="https://ideone.com/2DNzNJ"></iframe>
Neither mysqli_real_escape_string nor stripslashes protect against SQL injection.
Use prepared statements.
Example Code.
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "my_database");
/* Prepared statement, stage 1: prepare */
$stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)");
$id = 1;
$stmt->bind_param("i", $id);
$stmt->execute();

MySQL Real escape string

I have an insert function where I use MySQL real_escape_string() to remove illegal characters only its not actually removing those characters, can anybody see where I'm going wrong?
$interest = mysql_real_escape_string(urldecode($_GET['interest']));
$query = "INSERT INTO user_interests (user_id, interest) VALUES('{$user_id}' , '{$interest}')";
mysql_query($query) or die(mysql_error());
echo $interest;
There are no "illegal characters". mysql_real_escape_string just encodes all characters so that they can be safely put into a query. If you want to remove a character c, use str_replace:
$input = urldecode($_GET['interest']);
$input = str_replace('c', '', $input);
$interest = mysql_real_escape_string($input);
mysql_real_escape_string just escapes characters in your string that might cause problems when you try to write them to your database. This does not mean that it removes them.
Imagine you are taking user input and a user puts a quote into the input field. When you try to insert that string to your database, the quote will be interpreted as a quote in the sql query and the query won't work right.
INSERT INTO table (string)
VALUES ("this is a string with an extra " in it")
If you use mysql_real_escape_string on this string first, then your sql query will essentially look like this:
INSERT INTO table (string)
VALUES ("this is a string with an extra \" in it")
See the escape backslash above. You can see this extra quote even messes up the formatting here on SO.

How to insert a file path into a MySQL table using php?

I'm trying to insert a file path into an empty MySQL table with PHP 5 but slashes and other characters are removed so I can not use to the string when calling it from the table. What function do I use to preserve the file path without losing characters?
$rawpath = "F:\Business\test.htm";
$url = "Business";
$query = "INSERT IGNORE INTO `sites` (`url`,`base`)".
"VALUES ('$rawpath','$url');";
echo $query;
Outputs: INSERT IGNORE INTO sites (url,base) VALUES ('F:\Business\test.htm','Business');
$query = "SELECT * FROM `sites` WHERE `base`='Business';";
$row = mysql_query($query);
$url = mysql_result($row,0,"url");
echo $url;
Outputs: F:Businesstest.htm
Your problem is with backslashes \, which are used often to escape certain characters. You need to escape this backslashes (with another backslash), to make them appear. So, if you use double quotes, write \\ instead of just \, or use addslashes($url).
I'm not quite sure that you need to escape them if you use just single quotes.
You need to escape your back slashes. Try this
$rawpath = "F:\\Business\\test.htm";
Hope this helps.
You can just do: quotemeta($rawpath) before the insert statement. All the backslashes will be correctly escaped after that.

postgresql quotes problem

$url = "What's up with "You doing this"";
$q = sprintf ("update user set url='%s'",$url);
pg_query ($db_conn, $q)
I want to insert everything into the database exactly as the user wants. I don't want to escape anything. The above would fail for me because of the quotes. I know single quotes have to go around the postgresql string (url='%s'). Since there are double quotes in my url string the query will not update because of it. I'm sure I could do a string replace for all double quotes and make them single quotes but what if the user really wants double quotes. And I cannot use string replace to put a backslash because according to the postgresql docs the slash will be deprecated soon (http://www.postgresql.org/docs/8.1/interactive/sql-syntax.html) plus that goes against inserting only what the user inputted.
What do people suggest I do?
Use pg_escape_string to escape quote characters in your string.
Use parametrized queries:
pg_query_params
(
$db_conn,
"UPDATE user SET url = $1",
array('What's up with "You doing this"')
);
escape your double quotes in the text like this
$url = "What\'s up with \"You doing this\"";

Is Regex for Form Validation if I use the following?

I know there is no harm in adding it either way but I'm curious...
If I was to use htmlentities(); with ENT_QUOTES and then mysql_real_escape_string(); the variable before entering it into the Database, then just use html_entity_decode(); along with stripslashes(); to display the information...
Would this still be safe and secure?
You don't need to use htmlentities before storing data in the database. In fact, it makes things easier later if you don't. Only use htmlentities on strings as you echo them in HTML output (whether you fetched the string from a database or from some other source).
You don't need to apply stripslashes to data after you fetch it from the database. The database has not stored the extra escaping characters -- unless you applied double-escaping by mistake.
Here's the right sequence:
Get data from a form
$input = $_GET["input"];
Apply escaping once.
$quoted_input = "'" . mysql_real_escape_string($input) . "'";
Insert it into the database
$sql = "INSERT INTO MyTable (column1) VALUES ($quoted_input)";
$success = mysql_query($sql);
Later fetch it from the database
$sql = "SELECT column1 FROM MyTable";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
$data = $row["column1"];
Apply htmlentities once as you output.
echo htmlentities($data);
Maybe you can answer the question on your own if you know what these functions are intended to be used for:
htmlentities is to replace the HTML special characters &, <, >, and " and characters that can be represented by entity character references. This is used to encode data to be safely put out in any HTML context (especially with ENT_QUOTES so that it even can be used in single quoted attribute values). For example:
<textarea><?php echo htmlentities('</textarea>'); ?></textarea>
mysql_real_escape_string is to replace the special characters in a MySQL string while taking the connection character encoding into account (using mysql_client_encoding is required). This is used to encode data to be safely used in a MySQL string. For example:
$query = 'SELECT "'.mysql_real_escape_string("\n\r\t\v\f\\\"").'"';
html_entity_decode is the inverse function to htmlentities and replaces HTML character references (both numeric and entity character references).
stripslashes removed the escape character \.
If you just want to protect you from SQL injections, use mysql_real_escape_string for data that is used in MySQL queries. You could also use prepared statements or parameterized query builder (see SQL Syntax for Prepared Statements, PDO – Prepared Statements und Stored Procedures, MySQLi::prepare, et al.).
are you asking if you still need regex as form validation next to all those functions?
if that is what you are asking then in my opinion yes, you can never be safe enough. I've just written a validation class with functions that clean up the code and other functions with regex when I need a specific input.

Categories