nl2br not working on ical summary line feeds "\n" - php

I'm collecting a summary of an ical event in PHP. The thing is, that the summary contains line breaks \nand I want to replace them with <br> when inserting the events.
In my PHPMyAdmin after escaping the ical summary I see the characters \n, but without escaping the ical summary I can't see the characters \n. However, without escaping I can see actual real line-breaks. I need to escape the ical summary to make my database safe. Using the nl2br function is not working in both cases? Why?
CODE:
//without escaping
$title = $vevent->getProperty('summary');//Object method which retrieves the summary of an event
$title = nl2br($title);
//with escaping
$title = mysql_real_escape_string($vevent->getProperty('summary'));
$title = nl2br($title);

Hrm, what about reading the handbook page, my friend? http://php.net/manual/en/function.mysql-real-escape-string.php says
mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n,
Your line breaks are already SQL escaped. so you need to nl2br before.
And the usual rant I give to everyone: why are you using the mysql extension in 2011? It went out of fashion half a decade ago. Use mysqli or PDO and prepared statements, then you dont need to worry about escaping.

You can do it the other way around:
//with escaping
$title = nl2br($title);
$title = mysql_real_escape_string($vevent->getProperty('summary'));
But you shouldn't need to call nl2br before inserting into the database. It's better to do nl2br when you output the data to the browser. That way you store the actual data in the database (which later can be used in other context) and format it with HTML before outputting.

Related

Does escape order of strings matters in some way? (HTML and SQL injection)

We are developing a small website at school, so we were introduced to SQL injection in PHP and how to prevent it.
However I see most online examples and text books doing the following
$str = $_POST['user_input'];
$str = $mysqli->real_escape_string($str);
$str = htmlentities($str);
However I think the most logical way to validate input from users is:
$str = htmlentities($str);
$str = $mysqli->real_escape_string($str);
Does that make any difference for
Site accessibility (characters showed to end user, the string will just be "echoed" once retrieved from Database)
Preventing HTML and SQL injection (does wrong order allows injection?)
Performance of the server (for example one function is most expensive while the other increase string lenght, or just because the final string lenght is different and we want to save bytes on our Database)
?
Would be nice to cover also more escaping functions (maybe there is some dangerous combination/order that we should avoid).
I think that the right way is to search for escaping functions that outputs "dangerous characters" (dangerouse as HTML or as SQL, if any exist) and then just provide an input that generate those dangerous characters.
The order will result in different output.
The following code:
$string = 'Example " string';
echo htmlentities($mysqli->real_escape_string(($string))
. "\n"
. $mysqli->real_escape_string((htmlentities($string));
Results in:
Example \" string
Example " string
The output is different because if you escape the string before converting to HTML entities, it has a quote that needs escaping whereas if you do it in the reverse order the quote is replaced with the HTML entity and is a valid string value for MySQL.
That said, the two functions have entirely different purposes.
htmlentities is for converting strings to their HTML entities ready for output to a web browser.
real_escape_string is for converting a string for use between quotation marks in a MySQL query.
The two do not go together, you should store the text in the database (which will need escaping before being passed to) and convert to HTML entities when it comes to displaying it.
If you insist on storing the HTML entities version of the string in the database the correct way is to use htmlentities first, then escape it. Escaping of a string should be the last operation on it before passing to the database.
Doing it in the wrong way may result in stray backslashes as shown above, although when passed to MySQL these will actually be ignored as \& is not a valid escape sequence. You would only notice a difference if outputting the variable that was passed to the database (as opposed to later retrieving it from the database and then outputting it).
You may also want to look into prepared statements in mysqli:
http://www.php.net/manual/en/mysqli.prepare.php

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

keep textarea input format after using mysql_real_escape_string to store

I am using php5.3.6 and mysql 5.1.56 and CodeIgniter. Here is what I did.
Input some text in textarea, something like this:
what's this?
I'm bob.
$string = $_POST['name'];
$insertdata = mysql_real_escape_string($string);
Insert $insertdata into database.
It shows "what\'s this?\n\n\nI\'m bob."(without double quotes) in the table.
Query the data stored in database, use stripslashes on it and then put it back to the textarea.
It shows "what's this?nnnI'm bob."(without double quotes) in the textarea.
My questions are:
In step 4, shouldn't it be "what\'s this?\n\n\n I\'m bob." stored in the table?
I checked php manual. It says:
mysql_real_escape_string() calls
MySQL's library function
mysql_real_escape_string, which
prepends backslashes to the following
characters: \x00, \n, \r, \, ', " and
\x1a.
How am I supposed to keep the textarea input format after using mysql_real_escape_string()?
Is there anyway to choose which slash to strip and which not to?
Notes:
magic quotes option is off
I did not use stripslashes() before
using mysql_real_escape_string()
If I use addslashes() instead of
mysql_real_escape_string(),
everything works fine.
I don' want to use addslashes() since
it is not as secure as
mysql_real_escape_string(), as far as
I know.
Thanks,
Milo
This really does feel a lot like magic_quotes_gpc = On. Are you disabling it in php.ini or at runtime? It needs to be the former, otherwise it'll remain on.
http://www.php.net/manual/en/security.magicquotes.disabling.php
The magic_quotes_gpc directive may only be disabled at the system level, and not at runtime. In otherwords, use of ini_set() is not an option.
Short answer:
// double quotes are *very* important, or chars are not interpreted
$text_from_db=str_replace("\\r","\r",str_replace("\\n","\n",$text_from_db));
Long answer
Pretty simple but tricky.
You write your textarea and hit the "return" key, there is placed a \r\n (on Windows systems) with slashes that escape the "r" and "n" letter rising their special meaning of carriage return and newline.
You actually can't see them because they are "not printable" chars.
The slash char itself (0x1B) is invisible, that is a single slash is a "not printable" char, to make it visible you have to "transform" it in a printable slash char (0x5C) and to achieve that you have to double it "\\".
Now back to the question: if you can read the slash, probably that's beacuse that slash is not the 0x1B but rather 0x5C, so the "n" and "r" lose their special meaning and you get them as mere strings.
The code I posted does this conversion, converting the "[0x5C]n" string in a "[0x1B]" char.
Notes
Hope this helps, it did for me. IMPORTANT : it is not normal that the text that comes from the db has this issue if it has been stored correctly. My suggestion is to triple check insertion and retrieving because (given from the issue) you could be applying the quoting twice somewhere.
The Best Solution..
$insertdata = mysql_real_escape_string($string); (You can insert it in your database if you want)
echo stripslashes(str_replace('\r\n',PHP_EOL,$insertdata)); (The output is exactly as your input was)
You must escape data before inserting it into the database, to ensure you do not produce broken queries and to avoid SQL injections.
However, when you retrieve that data via a SELECT, you'll receive the data unescaped, ready to be used.
MySQL escapes the string, but when displaying the result back to you it will give you the same result as if it was unescaped.

How do I properly encode a form in php

On my site users can add content to the database via a form. I want the users to be able to type anything in the form and for it all to be added to the database how they have entered it. At the moment I'm getting problems with a number of characters, namely slashes, &, ? etc.
What is the best way to allow all characters to be added to the database correctly?
Also, do you have to decode them when displaying them for it to work correctly? If so, how do I do that?
When saving, use mysql_real_escape_string (or PDO) to protect against SQL injection attacks. This will make it possible to write quotes and backslashes without destroying the SQL query.
<?php
$text = mysql_real_escape_string($_POST['text']);
mysql_query('INSERT INTO table(text) VALUES("'.$text.'")');
?>
When printing the data to a browser (with echo), first run it through htmlspecialchars to disable HTML and solve your current problem:
<?php
// ...fetch $text from db here...
echo htmlspecialchars($text);
?>
htmlentities() may help you encode and decode html characters:
You can also use nl2br() to preserve line breaks from textarea elements:
Also you should use PDO for your database needs as it is much more secure than the old method of escaping data, mysql_real_escape_string()

Exporting data to a .sql format. How to escape?

I'm writing an export tool that converts input json data to sql statements.
This tool is (and should not) be aware of database connections, it should just output a .sql that can be used with other tools do the actual import.
Most of the mysqli->* and PDO-related functions rely on an open connection (to determine things like the characterset). What's a good way to go about this?
The reason the MySQL functions require a connection in order to escape the string is that all mysql_real_escape_string() does is make a call to MySQL's built-in escaping function.
However, if you read the manual page for it, you'll see that they do list the characters which are escaped:
mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.
You don't want to use addslashes() since that only escapes a few characters, and would not provide a secure solution. But you should be able to re-implement the escaping done by mysql_real_escape_string() using the list of characters given, with a simple call to strtr() or similar:
$replacements = array("\x00"=>'\x00',
"\n"=>'\n',
"\r"=>'\r',
"\\"=>'\\\\',
"'"=>"\'",
'"'=>'\"',
"\x1a"=>'\x1a');
$escaped = strtr($unescaped,$replacements);
#stefgosselin:
mysql_real_escape_string did require a connection.
I would go the line with least resistance. Means use a systemcall to exec mysqldumper > tmpfile
just a thought, is it possible for you app to generate and sql like
INSERT INTO table1 (id, name) VALUES (?, ?);
and pass a set of paramaters for the sql as an array
$parms = array('value1', 'value2');
and then have the part of your app that does do database work do the escaping at that point
function writeToDb($sql, $parms) {
// do escaping here
}
For escaping, mysql_real_escape_string function is the usual choice for this task except it does need a connection. The other alternative would be addslashes.
I would check out a mysqldump file tailored with the needed paramaters (character sets, drop tables, etc ..) and take it from there as a starting point.

Categories