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();
Related
When I post a variable to the database, of course, I use mysql_real_escape_string. This way special characters go in the database as it should.
When I read this variable out of the database, I use mysql_real_escape_string again together with stripslashes:
$var = stripslashes(mysql_real_escape_string($record['rowname']));
else it will give me slashes before quotes.
When I use this $var I mentioned above and want to echo it, I simple can echo "$var" because it has already been stripped and escaped, right?
And beside, if I use stripslashes + mysql_real_escape_string on a variable, then POST this same variable again in the database, is mysql_real_escape_string enough? Or do I need to stripslashes this variable again?
Summarized:
As I know how this works:
use mysql_real_escape EVERY time when using data with mysql: when reading query through variables just as posting variables to database.
Use stripslashes when echoing out escaped variables.
If you want to post stripslashes and escaped variables again to the database, you dont need to stripslash it again.
Do I miss htmlspecialchars?
EDIT
So this is all wrong?
while( $record=mysql_fetch_array($result) )
{
$custid=mysql_real_escape_string($record['custid']);
$custsurname=mysql_real_escape_string($record['custsurname']);
$custmidname=mysql_real_escape_string($record['custmidname']);
$custforename=mysql_real_escape_string($record['custforename']);
$custcountry=stripslashes(mysql_real_escape_string($record['custcountry'])); }
I'm afraid you're doing it wrong. The key point is that escaping is context sensitive and you completely disregard that fact.
On every data format, there're words or characters that are assigned special meanings in the format spec. For instance, a ' symbol in SQL means "string delimiter", a ? symbol in a URL means "start query string" and a < symbol in HTML means "start tag". You need escaping when you want to insert a literal word or character, i.e., you want to insert it as-is and remove its special meaning.
Once aware of that, it's clear that the syntax varies depending on the format and context. < means "start tag" in HTML but not in SQL or URLs. Thus you need to use a escaping method that's built for the target format and follows the format rules.
If you do mysql_real_escape_string() on data read from a database you're saying "escape my data so it can be injected as inside a SQL string". Your data gets ready to be used inside as a SQL string but get's corrupted for any other usage.
In this example, it happens that stripslashes() undoes most of what mysql_real_escape_string() did so you end up with an output that's basically unchanged. But that's pure chance.
Last but not least, having to escape database input parameters one by one is very annoying. All other DB extensions but the one you are using1 offer prepared statements. Don't get stuck with a deprecated extension that doesn't offer modern stuff.
1 Note: the legacy mysql extension has been deprecated for several years, when better alternatives became available, and it's no longer part of the language.
Update: a little clarification—escaping is just a syntax trick. You don't alter the input to the eyes of the target engine, which just sees the original data as-is. So there's no need to unescape the input when you retrieve it.
You don't need to stripslashes or mysql_real_escape_string the data coming from database, you just need to escape it before you query so the query parser knows what are special characters and what are literal characters.
stripslashes should be never used (as a hack to fix some symptoms), if you are going to need a variable after escaping it, use the original one:
$data_safe = mysql_real_escape_string( $data );
//$data can still be used normally
Escaping is only for a certain context, if the context is a mysql query then you will mysql real escape just for the query and nothing else. If the context is html output, then you will htmlescape just before outputting a string as html. At no point you want to actually modify the data itself. If you misunderstand this, you will see O\'Brian and O'Brian etc.
I'm doing this to all strings before inserting them:
mysql_real_escape_string($_POST['position']);
How do I remove the: \ after retriving them?
So I don't end up with: \"Piza\"
Also is this enough security or should I do something else?
Thanks
I would suggest you call $_POST['position'] directly (don't call mysql_real_escape_string on it) to get the non-escaped version.
Incidentally your comment about security suggests a bit of trouble understanding things.
One way of handling strings is to handle the escaped versions, which leads to one kind of difficulty, while another is to handle another and escape strings just before embedding, which leads to another kind of difficulty. I much prefer the latter.
use stripslashes() to get rid of the escape character.
Escaping is great. In case the value is going to be integer , I would suggest you do it like:
$value = (int) $_POST['some_int_field'];
This would make sure you always end up with an integer value.
It could be because magic quotes are enabled, so to make it versatile, use this:
if (get_magic_quotes_gpc()) { // Check if magic quotes are enabled
$position = stripslashes($_POST['position']);
} else {
$position = mysql_real_escape_string($_POST['position']);
}
mysql_real_escape_string() does add \s in your SQL strings but they should not be making it into the database as they are only there for the purpose of string parsing.
If you are seeing \s in you database then something else is escaping your stings before you call mysql_real_escape_string(). Check to make sure that magic_quotes_gpc isn't turned on.
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().
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.
I got this from for a login form tutorial:
function sanitize($securitystring) {
$securitystring = #trim($str);
if(get_magic_quotes_gpc()) {
$securitystring = stripslashes($str);
}
return mysql_real_escape_string($securitystring);
}
Could some one explain exactly what this does? I know that the 'clean' var is called up afterwards to sanitize the fields; I.e. $email = sanitize($_POST['email']);
Basically, if you have magic quotes switched on, special characters in POST/SESSION data will automatically be escaped (same as applying addslashes() to the string). The MySQL escape functions are better than PHP's addslashes() (although I can't remember the exact reasons why).
What your code does is check if the php.ini file has magic quotes turned on, if so the slashes are stripped from the data and then it is re-sanitised using the MySQL function. If magic quotes is not on, there is no need to strip slashes so the data is just sanitised with the MySQL function and returned.
First of all, this code is wrong.
It has wrong meaning and wrong name.
No SQL data preparation code does any cleaning or sanitization.
It does merely escaping. And this escaping must be unconditional.
and escaping shouldn't be mixed with anything else.
So, it must be three separated functions, not one.
Getting rid of magic quotes. Must be done separately at the data input.
trim if you wish. It's just text beautifier, no critical function it does.
mysql_real_escape_string() to prepare data for the SQL query.
So, the only mysql related function here is mysql_real_escape_string(). Though it makes no data "clean", but merely escape delimiters. Therefore, this function must be used only with data what considered as a string and enclosed in quotes. So, this is a good example:
$num=6;
$string='name';
$num=mysql_real_escape_string($num);
$string=mysql_real_escape_string($string);
$query="SELECT * FROM table WHERE name='$name' AND num='$num'";
while this example is wrong:
$num=6;
$string='name';
$num=mysql_real_escape_string($num);
$string=mysql_real_escape_string($string);
$query2="SELECT * FROM table WHERE name='$name' AND num=$num";
Even though $query2 would not throw a syntax error, this is wrong data preparation and mysql_real_escape_string would help nothing here. So, this function can be used only to escape data that treated as a string. though it can be done to any data type, there is some exceptions, such as LIMIT parameters, which cannot be treat as a strings.
trim() gets rid of all whitespace, and if magic quotes is on, the backslash is removed from any escaped quotes with stripslashes(). mysql_real_escape_string() readies a string to be used in a mysql query safely.
here are the docs for the functions used: http://php.net/manual/en/function.trim.php, http://php.net/manual/en/function.get-magic-quotes-gpc.php, http://php.net/manual/en/function.stripslashes.php, http://php.net/manual/en/function.mysql-real-escape-string.php
mysql_real_escape_string is used to escape characters in the string to add backslashes to characters such as ', which prevents an attacker from embedding additional SQL statements into the string. If the string is not escaped, additional SQL can be appended. For example, something along the lines of this might be executed:
SELECT * FROM tbl WHERE col = 'test' ; DELETE * FROM tbl ; SELECT 'owned'
magic_quotes does escaping of its own, although if I remember correctly its use is now discouraged. Besides, the MySQL function will do all the escaping you need to prevent SQL injection attacks.
Some (old) servers have magic_quotes enabled. That means that all external input is altered to (supposedly) escape it in order to be injected in a MySQL query. So O'Brian becomes O\'Brian. This was an early design decision by the PHP team that proved wrong:
You don't always need to inject input into database queries
Not all DB engines use back slashes as escape char
Escaping single quotes with backs slashes is not enough, even for MySQL
Your server security relies on a PHP setting that can be disabled
So it's way better to code without magic_quotes. The problem comes with redistributable code: you cannot know if the server will have magic_quotes enabled or disabled. So you can use get_magic_quotes_gpc() to detect it they're on and, if so, use stripslashes() to (try to) recover the original input.