I am encountered with the situation where one of my old code is using get_magic_quotes_gpc() which is deprecated in the latest PHP version 7.4.*
Currently, I have something like this.
Add Slashes
return get_magic_quotes_gpc() ? addslashes($string) : $string;
Remove Slashes
return get_magic_quotes_gpc() ? stripslashes($string) : $string;
Which is obviously giving error
Deprecated: Function get_magic_quotes_gpc() is deprecated
Question:
How can I fix it? So can work the same without using get_magic_quotes_gpc() function?
You need to remove every mention of this function from your code and do not replace it with anything else.
get_magic_quotes_gpc() has been useless ever since PHP 5.4.0. It would tell you whether you have magic quotes switched on in the configuration or not. Magic quotes were a terrible idea and this feature was removed for security reasons (PHP developers believed in magic & superstitions and wrote unsecure code).
Most likely even you yourself do not know why you had this line of code in your project. I know I was fooled by it when I was learning PHP. The reality is you do not need it at all. This function has nothing to do with security and the concept of input sanitization is preposterous.
Instead, rely on good security guidelines.
Use parameterized prepared statements for interactions with the database. PHP has a very good library called PDO, which can be used with many DB drivers including MySQL.
If you produce output, then escape the output taking into consideration the rules of that medium. For example when outputting to HTML use htmlspecialchars() to prevent XSS.
Never sanitize input. There is no magical solution that would protect you against everything. Instead, you as a developer must be aware of dangers and you need to know how to protect your code. Don’t try to sanitize input. Escape output.
Replace get_magic_quotes_gpc() with false.
Then simplify complex expressions by removing the unreachable branches. E.g.
return get_magic_quotes_gpc() ? addslashes($string) : $string;
becomes simply
return $string;
Related
As always I start this saying that I am learning.
I saw in several books and even here, that a lot of user when we are talking about sanitize, for example, Form>Input>Submit, they use
function sanitizeexample($param)
{
$param = stripslashes($param);
$param = strip_tags($param);
$param = htmlentities($param);
return $param;
}
$name = sanitizeexample($_POST['name']);
Instead of JUST:
function sanitizeexample($param)
{
$param = htmlentities($param);
return $param;
}
$name = sanitizeexample($_POST['name']);
So here the question. Do stripslashes() and strip_tags() provide something else regarding to security? Or it´s enough with htmlentities().
And I´m asking JUST to know which is the best to use.
Whether strip_tags() provides a value-add is dependent on your particular use case. If you htmlentities() a string that contains html tags, you're going to get the raw html content escaped and rendered on the page. The example you give is probably making the assumption that this is not what you want, and so by doing strip_tags() first, html tags are removed.
stripslashes is the inverse to addslashes. In modern (PHP >= 5.4) PHP code, this is not necessary. On legacy systems, with magic_quotes_gpc enabled, user input from request variables are automagically escaped with addslashes so as to make them "safe" for direct use in database queries. This has widely been considered a Bad Idea (because it's not actually safe, for many reasons) and magic_quotes has been removed. Accordingly, you would now not normally need to stripslashes() user input. (Whether you actually need to is going to be dependent on PHP version and ini settings.)
(Note that you would still need to properly escape any content going into your database, but that is better done with parameterized queries or database-specific escaping functions, both of which are outside the scope of this question.)
It depends on your goals:
if you're getting user's data passed from html form - you should
definitely apply strip_tags(trim($_POST['name'])) approach to
sanitize possible insecure and excessive data.
if you are receiving uploaded user's file content and need to save
content formatting - you have to consider how to safely process and
store such files making some specific(selective) sanitizing
I've found the following code that checks if the stripslashes() function exists.
if ( function_exists( 'stripslashes' ) ) {
// Do something
} else {
// Do something
}
The stripslashes() function works on PHP4 and PHP5, so I wonder why it needs a conditional statement to check if the function exists. I don't get it.
It's not a subjective question. Just tell me what is the difference between the usage of this statement and not using it. Thanks in advance!
Here are related links as to where they were used:
http://trevordavis.net/blog/wordpress-jquery-contact-form-without-a-plugin/
PHP contact form will not submit
There used to be a feature in PHP known as magic quotes, which while well-intentioned, has caused endless confusion.
Most likely this code is intended to detect magic quotes, however this is not the correct way to do this, especially since it does not work.
The correct way to detect if magic quotes are enabled is to use the fuction made for the purpoes, get_magic_quotes_gpc like so.
if (get_magic_quotes_gpc()) {
Or perhaps the following, if you are concerned this will be removed.
if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
That being said, the whole magic quotes feature was removed back in PHP 5.4, so unless you need to support obsolete versions of PHP, you can just forget the whole thing ever existed (unless you use WordPress that is...).
On a side note, I suppose it's possible the stripslashes function may be removed in the future, and may not have existed at one point, but in this context that's probably not the reason.
Sidenote: Transcribed from some of my comments (slightly modified) to supply the question with a complimentary answer to that of Alexander's.
This is probably to check if some coder went and created a custom function called the same (a method to someone's madness?), or somebody hacked the PHP core and removed it; I'm speculating of course, it's not impossible.
However, the same thing goes for if ( function_exists( 'mysql_real_escape_string' ) ).
If a server doesn't support those old and deprecated mysql_ functions, then the conditional statement is needed and would prove to be effective/useful for something of that nature to be used.
References: (mysql_ removed as of PHP 7, and other deprecation notices)
https://wiki.php.net/rfc/mysql_deprecation
https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7
https://wiki.php.net/rfc
Personally, function_exists() should only be used against probable deprecated functions; mysql_ being one of them and session_register() - I'm sure there are more.
It's listed in the manual from contributed notes http://php.net/manual/en/function.stripslashes.php and it seems to have something to do with magic_quotes_gpc as per what Alexander (O'Mara) said in comments.
N.B.:
I am by no means looking to gain anything from this, but for others visiting the question.
Currently I use this strategy:
After submitting a HTML form or data sent using jQuery's $.get() or $.post() I need to know what is come and then apply logic on the basis of that.
suppose, I've got $_POST['username'], $_POST['password'] and $_POST['login_submit_button'].
In my processing script file, I do like this:
if(isset($_POST['login_submit_button']) && isset($_POST['username']) && $_POST['username'] != "" && isset($_POST['password']) && $_POST['password'] != "") {
// calling a common function safe_vars() which does
// mysql_real_escape_string(stripslashes(trim($any_variable_need_to_become_safe)))
// and now using the above variables for different purposes like
// calculation, insertion/updating old values in database etc.
}
I know all this logic is wrong or having serious issues, so I want a much-secure and perfect solution instead of this. I welcome to find out vulnerabilities and severe security-bleaches in my strategy. This question can help others too, if answers came more explanatory, this can be informative community wiki.
There is no way to make a generic super "make things safe" function.
mysql_real_escape_string
You shouldn't use this at all. It uses the old mysql API, and assumes you are going to be manually smashing strings together to make SQL. Don't do that. Use PDO or mysqli and a function that deals in prepared queries and bound arguments.
stripslashes
This is an antidote to magic quotes. If magic quotes are not on it will destroy data. Don't use it. Turn magic quotes off instead.
trim
This destroys data. Don't use it unless you really want to remove white space at the start and end of the string.
Escape data for the target language immediately before inserting data into that language.
For SQL, use bound arguments and prepared queries.
For HTML, use htmlspecialchars or a template language that does escaping for you, such as mustache.
Alternatively, (if you want to allow HTML) parse it, generate a DOM, filter it using a whitelist, then serialise it back to HTML.
For JSON, use encode_json
etc.
You only need to stripslashes if you have magic_quotes enabled (use get_magic_quotes_gpc to check)
You should white list filter your POST vars using filter_var or ctype_* or preg_match (as well as checking bound conditions such as length and presence)
Use prepared statements / PDO for your queries to ensure proper escaping
Escape any html output with htmlentities
Nothing is bullet proof, however the above are good practices to avoid SQL injection / XSS.
I'm quite confused now and would like to know, if you could clear things up for me.
After the lateste Anon/Lulsec attacks, i was questioning my php/mysql security.
So, i thought, how could I protect both, PHP and Mysql.
Question: Could anyone explain me, what's best practice to handle PHP and Mysql when it comes to quotes?
Especially in forms, I would need some kind of htmlspecialchars in order to protect the html, correct?
Can PHP be exploitet at all with a form? Is there any kind of protection needed?
Should I use real_escape_string just before a query? Would it be wrong/bad to use it already within PHP (see sanitize_post function)?
Currently i'm using the following function. The function "sanitizes" all $_POST and $_GET variables. Is this "safe"?
function sanitize_post($array) {
global $db;
if(is_array($array)) {
foreach($array as $key=>$value) {
if(is_array($array[$key])) {
$array[$key] = sanitize_post($array[$key]);
} elseif(is_string($array[$key])) {
$array[$key] = $db->real_escape_string(strtr(stripslashes(trim($array[$key])), array("'" => '', '"' => '')));
}
}
} elseif(is_string($array)) {
$array = $db->real_escape_string(strtr(stripslashes(trim($array)), array("'" => '', '"' => '')));
}
return $array;
}
I'm using PHP 5.3.5 with Mysql 5.1.54.
Thanks.
mysql_real_escape_string deserves your attention.
However direct queries are a quagmire and no longer considered safe practice. You should read up on PDO prepared statements and binding parameters which has a side benefit of quoting, escaping, etc. built-in.
BEST practice is always to use prepared statements. This makes SQL injection impossible. This is done with either PDO or mysqli. Forget about all the mysql_* functions. They are old and obsolete.
Question: Could anyone explain me, what's best practice to handle PHP
and Mysql when it comes to quotes?
That's easy: Use prepared statements, e. g. with PDO::prepare or mysqli_prepare.
There is nothing like "universal sanitization". Let's call it just quoting, because that's what its all about.
When quoting, you always quote text for some particular output, like:
string value for mysql query
like expression for mysql query
html code
json
mysql regular expression
php regular expression
For each case, you need different quoting, because each usage is present within different syntax context. This also implies that the quoting shouldn't be made at the input into PHP, but at the particular output! Which is the reason why features like magic_quotes_gpc are broken (always assure it is switched off!!!).
So, what methods would one use for quoting in these particular cases? (Feel free to correct me, there might be more modern methods, but these are working for me)
mysql_real_escape_string($str)
mysql_real_escape_string(addcslashes($str, "%_"))
htmlspecialchars($str)
json_encode() - only for utf8! I use my function for iso-8859-2
mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) - you cannot use preg_quote in this case because backslash would be escaped two times!
preg_quote()
Don't waste the effort using mysql_real_escape_string() or anything like that. Just use prepared statements with PDO and SQL injection is impossible.
I usually use the PHP functions stripslashes and strip_tags on the variables as they come in via $_POST (or $_GET, depending on what you use) and mysql_real_escape_string during the query. (I'm not sure if this is "right" but it's worked for me so far.) You can also use PHP's built in validate filters to check things like email addresses, url's, data types, etc. PDO is supposedly decent at preventing SQL injection but I haven't had any experience with it yet.
The basic workflow should be
$data = $_POST['somefield which will go into the database'];
... do data validation ...
if (everything ok) {
$escaped_data = escape_function($data);
$sql = " ... query here with $escaped_data ... ";
do_query($sql);
}
Basically, data that's been escaped for database insertion should ONLY be used for database insertion. There's no point in pre-processing everything and overwriting all data with db-escaped values, when only 2 or 3 of 50(say) values actually go anywhere near the db.
Ditto for htmlspecialchars. Don't send data through htmlspecialchars unless it's headed for an HTML-type display.
Don't store data in the DB formatted for one particular purpose, because if you ever need the data in a different form for some other purpose, you have to undo the escaping. Always store raw/unformatted data in the db. And note: the escaping done with mysql_real_escape_string() and company does not actually get stored in the db. It's there only to make sure the data gets into the database SAFELY. What's actually stored in the db is the raw unescaped/unquoted data. Once it's in the database, it's "safe".
e.g. consider the escaping functions as handcuffs on a prisoner being transferred. While the prisoner is inside either jail, cuffs are not needed.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
PHP: the ultimate clean/secure function
I found this code snippet here: http://snipplr.com/view/12853/clean-variables-from-sql-injections/
The author claims:
This little function helps to fight common security issue with SQL injections, it can sanitize any global variable like $POST, $GET, $_SERVER etc and escape unsafe characters.
Is this code safe?
function _clean($str){
return is_array($str) ? array_map('_clean', $str) : str_replace("\\", "\\\\"
, htmlspecialchars((get_magic_quotes_gpc() ? stripslashes($str) : $str)
, ENT_QUOTES));
}
//usage call it somewhere in beginning of your script
_clean($_POST);
_clean($_GET);
_clean($_REQUEST);// and so on..
Please enlighten me whether this is safe, 'cause it looks jury-rigged to me.
Generic code cleaning functions are always a bad idea. They will break your data in one way or the other. Never use them; sanitize data right before it gets used, with the right sanitation method for the intended use.
Duplicate: PHP: the ultimate clean/secure function
Just use mysql_real_escape_string if you need to escape special characters for a mysql database. I'd figure other databases support similar functions too.
This snipped tries some silly replaces and may be pretty safe, but could just as well mess up your data too. Why reinvent the wheel?
Why wouldn't you just use the built-in escaping/parameterizing functionality for your database? I agree with it looking jury-rigged, go with the function built by the people who made the database library.
It's not safe (no addslashes or mysql_real_escape_string there), not optimal in performance too (get_magic_quotes_gpc being called for each variable).