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.
Related
I have problems using mysqli_real_escape_string for storing text in PHP
The text I would like to store:
tesing%2Bsmaple%2Bid
Then I use the method:
$id = mysqli_real_escape_string($con, $query['ID']);
echo $id;
The text changes to:
tesing+smaple+id
Why does the text change and what should I do if I don't want it to automatically convert it?
Please help
htmlspecialchars converts characters with special meaning in HTML into entities. That is essential if you have some text that you want to insert into an HTML document (as it stops, for instance, characters such as < being treated as the start of tags, and protects against XSS).
mysql_real_escape_string converts characters with special meaning in MySQL SQL queries into escapes. This allows you to insert arbitrary strings into a MySQL database safely (protecting against errors and injection. There are, however, better ways to do the same thing.
try this:
$id = mysql_real_escape_string(htmlspecialchars($query['ID']));
echo $id;
Best way is to base64_encode() the value before storing and base64_decode() it while pulling from database. You wont loose any information :)
<?php
$myvar = "tesing%2Bsmaple%2Bid";
$vartostore = base64_encode($myvar);
echo $vartostore;
$varfromdb = base64_decode($vartostore);
echo $varfromdb;
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
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.
to sanitize user input we usually use mysql_real_escape_string, but for example if i want to escape: O'Brian it will return O\'Brian and I don't really like this because if i want to print this name, I have to strip slasheseverytime.
So I thought to use this function:
$search = array("'", '"');
$replace = array("´", "“");
$str_clean = str_replace($search, $replace, "O'Brian");
Is this simple function protecting me from MySQL-Injection?
Thank very much and sorry for my bad English.
No - no more escaping!
Use mysqli or PDO and prepared statements
http://php.net/manual/en/mysqli.prepare.php
http://php.net/manual/en/pdo.prepared-statements.php
mysql_real_escape_string does add the \ for string escaping only and does not add them to the database, so you don't have to use stripslashes while displaying the content.
If you are really getting the \ stored in the database, do off the magic_quote
You should always use mysql_real_escape_string to escape input. This is for when you're writing values into your database, not when you're reading values from your database. When you write "O\'Brian" to your database, it's stored as "O'Brian", and when you read it back out, you should also get "O'Brian" (and won't need to strip the slashes, since they don't exist).
Yes, obviously it's protecting from SQL Injection attacks
It Escapes special characters in the unescaped_string, taking into account the current character set of the connection so that it is safe to place it in a mysql_query().
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.