PHP's htmlspeciachars not working on single quotes - php

I'm trying to convert a single quote into its relevant HTML code for database insertion, but it does not appear to be working. When I create the following script:
<?php
$str = "& and ' and \" and < and >";
echo htmlspecialchars($str);
?>
My browser returns the following:
& and ' and " and < and >
What am I doing wrong? I've read the PHP manual on htmlspecialchars() function and it says it applies to single quotes, but it doesn't seem to be working for me.

Use htmlentities() with the flag ENT_QUOTES. From the manual:
ENT_QUOTES Will convert both double and single quotes.
htmlentities($text, ENT_QUOTES);
If you just want to replace ' to ' you could use str_replace(), of course:
str_replace("'", "'", $text);
However, since you want to insert the data into SQL code, please look into prepared statements in PDO or MySQLi. These functions serve the exact purpose you need (from what I can tell) and will be better than your own function. After all, why reinvent the wheel?
Just for the record, be sure not to use the deprecated MySQL functions in PHP – as explained in _Why shouldn't I use mysql__* functions in PHP?.

Related

PHP MySQLi escape quotes

I am using PHP/mysqli to read in comments, but various comments in the table have either a single quote or a double quote.
I am storing the comments in a data-attribute. Using the Chrome console, I can see where the quote is throwing the whole code out of whack.
<?php
echo "<td><a href='' class='comment' data-toggle='modal' data-comment='".htmlentities($row[comment])."'>" . $row[partner_name] . "</a></td>";
?>
As you can see in the code above, I tried to use htmlentities. I also tried addslashes and a combination of the two.
Either way, I still can't get the comment to display properly because of the quote inside the mysql table.
Is there another PHP function that I can use to fix this?
Directly above is a screen shot from the Chrome console. Right after the words POTENTIAL 53 there is a single quote that is throwing my code off. All the other orange text is being read as HTML when it's supposed to be part of the comment.
There has to be a way to read the single quote as part of the string.
Pass the flag, ENT_QUOTES, to your htmlentities function. See http://php.net/htmlentities. This will replace quotes with entified quote and prevent it from breaking out of the data-comment attribute.
Well, there are two problems:
You have to encode stuff, especially quotes:
$text = htmlentities($value, ENT_QUOTES);
The title attribute does not work with newlines, so you will have to deal that. Something like this should do the job:
$text = preg_replace('/\r?\n/', '#xA;', $text);
Try escaping the quotes in your data. Something to this affect:
$pattern = "/\"|\'/";
$replace = '\\\"';
$subject = $row[comment];
$rowComment = preg_filter($pattern, $replace, $subject);
*Tip - You can also filter the data before storing it.
Description: echo $rowComment will produce a string with all quotes escaped;

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();

single qoute syntax printing in php [duplicate]

This question already has answers here:
single quote inside double quote in php
(3 answers)
Closed 9 years ago.
The below outputs
href="javascript:showBed(" a114:1')'
when I want it on the form
href="javascript:showBed('A114:1')"
in order to get javascript to work. I had a look at this site but coudn't get it to work so I gave up. Perhaps you could give me a hint on how the corrent syntax would be?
echo("<a href='javascript:showBed('" . $row['Bed'] ."')' target='main' class='larmlink'>link</a>");
Thanks =)
Your output is not what it would output, but it is how it would be interpreted (HINT: don't look at a parsed DOM tree, look at the source).
echo("<a href='javascript:showBed('" . $row['Bed'] ."')' ...
==>
echo("<a href=\"javascript:showBed('" . $row['Bed'] ."')\" ...
You really should be using the more standard double quotes around HTML element properties. As such, it is probably best to use single quotes in PHP. I would suggest this:
echo('link');
To print the double-quote character, you can escape it by doing \"
echo("<a href=\"javascript:showBed('" . $row['bed'] ."')\" target='main' class='larmlink'>link</a>");
Live demo
When you want to output variable data to JavaScript, it is good to use json_encode() so that all special characters are escaped automatically. The htmlspecialchars() escapes any values for use in the HTML attribute value.
echo '<a href="',
htmlspecialchars('javascript:showBed(' . json_encode($row['Bed']) . ')'),
'" target="main" class="larmlink">link</a>';
Note that I use single quotes for PHP string literals so that PHP doesn't have to search through my string for a variable to replace. You don't have to do this, but I recommend it.
I like to use sprintf (or printf, but sprintf is easier to refactor) for long strings like this so it's easy to see the template:
echo sprintf("<a href='javascript:showBed(\"%s\")' target='main' class='larmlink'>link</a>", $row['Bed']);
I'd also consider using addslashes on the $row['Bed'] variable in case it has quotes in it.
Using the heredoc syntax often makes code with mixed quotes easier to understand:
echo <<<EOD
link
EOD;
As others mentioned, if the value of your $row['Bed'] might contain single or double quotes, you have to escape it with addslashes.
You can use the heredoc syntax to avoid to escape anything:
echo <<<LOD
link
LOD;
Notice that if your variables contains some quotes you must use the addslashes function or str_replace before.
Another good practive is to separate systematically all the html content from php code:
<a href="javascript:showBed('<?php
echo $row['Bed'];
?>')" target="main" class="larmlink">link</a>
try this one:
echo("<a href='javascript:showBed(\"" . $row['Bed'] ."\")' target='main' class='larmlink'>link</a>");

How to store escaped characters in MySQL and display them in php?

For example I want to store the String "That's all". MySQL automatically escapes the ' character. How do I echo that String from the database using php but remove the \ in front of escaped characters like \' ? I would also like to preserve other formatting like new lines and blank spaces.
Have you tried stripslashes(), regarding the linebreaks just use the nl2br() function.
Example:
$yourString = "That\'s all\n folks";
$yourString = stripslashes(nl2br($yourString));
echo $yourString;
Note: \\ double slashes will turn to \ single slashes
You should probably setup your own function, something like:
$yourString = "That\'s all\n folks";
function escapeString($string) {
return stripslashes(nl2br($string));
}
echo escapeString($yourString);
There are also several good examples in the nl2br() docs
Edit 2
The reason your are seeing these is because mysql is escaping line breaks, etc. I am guessing you are using mysql_* functions. You should probably look into mysqli or PDO.
Here is an example:
$yourString = "That's all
folks";
echo mysql_escape_string($yourString);
Outputs:
That\'s all\r\n folks
If you use prepared statements, those characters will not be escaped on insert.
Use stripslashes() to remove slashes if you cannot avoid adding slashes on input.
At first, magic_quotes_gpc escapes the character like ' or ". You can also disable this in your php.ini. But then you should escape the things yourself that no query can get "infected".
Lookup mysql injection for more information.
When the escaped string is been written in your database. The string doesn't contain theses escape charakters and when you output them again. You should see the result as you want it.
Me for myself prefer the method by storing everything without escapes and escape or display things when I output them. You could also easily use an str_replace("\n", "", $text) to prevent newslines are displayed.
Greetings MRu

Apostrophe issue

I have built a search engine using php and mysql.
Problem:
When I submit a word with an apostrophe in it and return the value to the text field using $_GET the apostrophe has been replaced with a backslash and all characters after the apostrophe are missing.
Example:
Submitted Words: Just can't get enough
Returned Value (Using $_GET): Just can\
Also the url comes up like this:search=just+can%27t+get+enough
As you can see the ' has been replaced with a \ and get enough is missing.
Question:
Does anybody know what causes this to happen and what is the solution to fix this problem?
The code:
http://tinypaste.com/11d62
If you're running PHP version less than 5.3.0, the slash might be added by the Magic Quotes which you can turn off in the .ini file.
From your description of "value to the text field" I speculate you have some output code like this:
Redisplay
<input value='<?=$_GET['search']?>'>
In that case the contained single quote will terminate the html attribute. And anything behind the single quote is simply garbage to the browser. In this case applying htmlspecialchars to the output helps.
(The backslash is likely due to magic_quotes or mysql_*_escape before outputting the text. I doubt the question describes a database error here.)
Update: It seems it's indeed an output problem here:
echo "<a href='searchmusic.php?search=$search&s=$next'>Next</a>";
Regardless of if you use single or double quotes you would need:
echo "<a href='searchmusic.php?search="
. htmlspecialchars(stripslashes($search))
. "&s=$next'>Next</a>";
(Notice that using stripslashes is a workaround here. You should preserve the original search text, or disable the magic_quotes rather.)
Okay I forgot something crucial. htmlspecialchars needs the ENT_QUOTES parameter - always, and in your case particularly:
// prepare for later output:
$search = $_GET['search'];
$html_search = htmlspecialchars(stripslashes($search), ENT_QUOTES);
And then use that whereever you wanted to display $search before:
echo "<a href='searchmusic.php?search=$html_search&s=$next'>Next</a>";
Single quotes are important in PHP and MySQL.
A single quote is a delimeter for a string in PHP, for example:
$str = 'my string';
If you want to include a literal quote inside a string you must tell PHP that the quote is not the end of the string. It is escaped with the backslash, for example:
$str = 'my string with a quote \' inside it';
See PHP Strings for more on this.
MySQL operates in a similar way. An example query might be:
$username = 'andyb';
$quert = "SELECT * FROM users WHERE user_name = '$username'";
The single quote delimits the string parameter. If the $username included a single quote, this would cause the query to end prematurely. Correctly escaping parameters is an important concept to be familiar with as it is one attack vector for breaking into a database - see SQL Injection for more information.
One way to handle this escaping is with mysql_real_escape_string().

Categories