mysql_real_escape_string for all $_POST [duplicate] - php

This question already has answers here:
Is is bad practice to use array_walk with mysqli_real_escape_string?
(1 answer)
How can I prevent SQL injection in PHP?
(27 answers)
Closed 1 year ago.
I have a old system without any check for sql injection and I want to add mysqli_real_escape_string() every time user intract with the DB.
All of the system is built under index.php. the page look like that:
if (!isset($_GET['p'])) {
$_GET['p'] = 'main';
}
if (!file_exists($_GET['p'].".php")) {
echo "The page you are looking for isn't exist.";
} else {
if (logs()) {
include($_GET['p'].".php");
}
else {
include('not_register.php');
}
}
I thought of just adding this code in the top oh index.php and I wanted to be sure I'm not messing up with anything so i'm asking here.
foreach ($_POST as $name => $val) {
$_POST[$name] = mysqli_real_escape_string($db, $val);
}
This code running every reload of page will have any negative influence?
thx.

This:
I want to add mysql_real_escape_string() every time user intract with
the DB.
Is a good goal for legacy mysql code that is using mysql_* functions. However, this:
foreach ($_POST as $name => $val) {
$_POST[$name] = mysqli_real_escape_string($db, $val); }
is a different thing. You're not adding it to every time user interacts with DB, you're adding it done every time, before anything else has been done. The function needs a connection to the database, so if you don't have such a connection in a page that uses these variables, you immediately hit into issues. Furthermore, you can break any handling of those variables that might not expect the values to be escaped at this point - they should be escaped for DB usage, so immediately before using them with the database, not before that.
Also, as others have noted, your code is vulnerable to injections with your include pattern. file_exists can be used with network shares, file paths as well as some url wrappers. To quote file_exists manual entry:
As of PHP 5.0.0, this function can also be used with some URL
wrappers. Refer to Supported Protocols and Wrappers to determine which
wrappers support stat() family of functionality.
Even without url wrappers, a malicious user can use your include to directly include some server configs and other files you don't want to be included.

First.
Running this question an a loop will help noone. In fact, you just reinvented a notorious magic quotes feature, that is already removed from the language. For a reason.
Second.
It is NOT good goal for legacy mysql code that is using mysql_* functions. Just because this function has nothing to do with injections at all.
If you have only 25 pages - just review them all and rewrite SQL handling code properly

Related

Upgrading PHP - Need to remove get_magic_quotes_gpc

We're upgrading from php 5.3 to 5.4, which is not backwards compatible for 'get_magic_quotes_gpc'. I understand the code will still work, sort of, but just bring back a FALSE each time.
However, I think the time has come to scrub this from our code.
Here's a typical example:
$product_id = "0";
if (isset($HTTP_GET_VARS["id"])) {
$rid = (get_magic_quotes_gpc()) ? $HTTP_GET_VARS["id"] : addslashes($HTTP_GET_VARS["id"]);
}
//then $product_id gets used all over the place in many different queries
I've been researching how to fix this and this is what I came up with:
$rid = "0";
if (isset($HTTP_GET_VARS["id"])) {
$rid = addslashes($HTTP_GET_VARS["id"]);
}
I'm a little over my head here. I know this all has to do with SQL injection and such. Is my solution an reasonable/acceptable one?
Thanks in advance.
<<<< EDIT - ADDITIONAL INFORMATION >>>>
Thanks for the replies. Actually, we did a bunch of conversion to PDO about 18 mos ago (mostly due to this type of advice on stackoverflow :)
So, I may have some reduntant, pointless code going on. Here's the full picture of what is happening below the code I posted above that gets the variable from the URL.
You'll see, there is the (get_magic_quuotes_gpc) that used to be there, now commented out and replaced by the (addslashes). But that variable is passed on to a PDO query.
$product_id = "0";
if (isset($HTTP_GET_VARS["id"])) {
//$product_id = (get_magic_quotes_gpc()) ? $HTTP_GET_VARS["id"] : addslashes($HTTP_GET_VARS["id"]);
$product_id = addslashes($HTTP_GET_VARS["id"]);
}
// NEW QUERIES - BEG xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
try {
# MySQL with PDO_MYSQL
$pdo = new PDO("mysql:host=$hostname_db;dbname=$database_db", $username_db, $password_db);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
// Query 1: product details
$stmt = $pdo->prepare('SELECT
[a bunch of stuff here, fields, joins, etc]
WHERE product_id = ? ');
$stmt -> execute(array($rid));
$row_count_resto_details = $stmt->rowCount();
$row_resto_details = $stmt->fetch(PDO::FETCH_ASSOC);
}
// Error message for pdo
catch(PDOException $e) {
echo $e->getMessage();
}
// END QUERY xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Can I just get rid of all the stuff in the first 4-5 lines of code and just make it this:
$product_id = $HTTP_GET_VARS["id"];
No, it's not reasonable.
The problem is, the "magic quotes" feature was a bad idea in the first place, so trying to replicate it only means that you've relied on a broken solution until now, and your application is without a doubt vulnerable to SQL injection attacks.
"Why is magic quotes a broken solution?", you'd probably ask. And the answer is kind of hidden in the question itself - security and IT in general aren't and can't be magic. Whenever you see a solution that advertises itself or at least seems to work in a "magic" way, know that it is bad and you should never trust it.
What you need instead are context-aware solutions, and in the case of preventing SQL injections - that's parameterized queries. You should read this to learn more: How can I prevent SQL-injection in PHP?
I'd also urge you to upgrade straight to PHP 5.6, mostly for two reasons:
PHP 5.4 will reach its End Of Life in a month and that alone makes it a possible security risk.
You have no reason not to. Honestly, the upgrade path is a breeze and comes with very little backwards-compatibility concerns, if any at all. PHP is much more stable now, there are very few significant changes since 5.3 vs 5.4.
Update (to answer the extended question):
You not only can remove the addslashes() logic, but you MUST do that - if you leave it, it will add slashes to some of your input data and these slashes will be a part of the data itself.
What you want to do instead is to validate input data - check if it is in the proper format in the first place. For example, if you expect a numeric ID - check if it only contains digits before using it.
Also, $HTTP_GET_VARS has been deprecated since PHP 4.1 and you should be using $_GET instead.

magic-quotes is ON && usage of stripslashes AND mysql-real-escape-string TOGETHER [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to prevent SQL injection in PHP?
i am on a free php server, I don't have access to php.ini file and magic_quotes is ON. so while I add records into mysql via my form page, my php code is
$_POST["text"]=trim(stripslashes(mysql_real_escape_string($_POST["text"])));
my question:
i want to eliminate magic_quote effect since it'll depreciate&removed AND put potentially malicious user
input into mysql in best way. So does my code above correct or do I need change,
improvement?
thanks,
Just stripslashes() is enough to get rid of the magic quotes.
$text = stripslashes($_POST["text"]);
See a more complete example of removing magic quotes at runtime: http://php.net/manual/en/security.magicquotes.disabling.php
You really should get a different PHP server. Magic quotes have been deprecated since PHP 5.3.0 (June 2009). Your PHP hosting site hasn't updated PHP in almost four years, and you're at risk of many other bugs and even security vulnerabilities. It's time for you to move to another host.
Re your comments:
Yes, stripslashes just converts the request parameter to plain text.
As for the question of whether you should use mysql_real_escape_string()...
First, you should do that only if you are interpolating the value into an SQL query. You aren't necessarily going to do that with every POST value, so it's dumb to apply the escaping to everything.
By analogy, it'd be like putting your dinner into refrigerator storage containers before you know how much you will eat and how much you will have as leftovers. :-)
Second, you shouldn't be using the mysql_* functions anymore at all. They are deprecated as of PHP 5.5.0, and they will be removed in a future version of PHP. You should start now using mysqli_* or PDO functions.
Third, you shouldn't use escaping at all for dynamic values in SQL queries. Instead, use prepared queries with parameters. Parameterized queries are more secure, easier to code, and faster to run than using mysql_real_escape_string().
Re your next comment:
No, I don't think you have got it yet.
If you want to insert $_POST["text"] into an SQL query, and magic quotes is ON, here's what you do:
// remove the magic quotes simply with stripslashes():
$text = stripslashes($_POST["text"]);
// prepare an SQL statement, using a ? placeholder instead of interpolated value
$stmt = $mysqli->prepare("INSERT INTO mytable (mytext) VALUES (?)");
// always check for an error on prepare, you might have made a syntax error,
// or the table might not exist, etc.
if ($stmt === false) {
die($mysqli->error);
}
// bind one PHP variables for each parameter placeholder in the query
$stmt->bind_param("s", $text);
// then execute! MySQL will use the values of the PHP variables you bound
// in place of the placeholders
$status = $stmt->execute();
// always check for an error on execute too, because the value of the parameter
// might cause the query to fail, e.g. conflicting with another value in a
// unique column, etc.
if ($status === false) {
die($stmt->error);
}
There is no case where you need to use mysqli_real_escape_string() if you use query parameters.
If you need more help, here's a tutorial on mysqli with examples showing bound parameters:
http://devzone.zend.com/239/ext-mysqli-part-i_overview-and-prepared-statements/

Is this sufficient security for user input in PHP [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
The ultimate clean/secure function
After reading up on PHP security I have the feeling that anything I code is always insecure. So to combat the security issues of user input I have created a function that allows me to escape and strip user input for any usage situation.
I would just like to know if this is in fact secure and if I could make it more secure. Also what kind of attacks would this prevent? From what I can tell XSS by using _GET, HTML input and MYSQL injection would have been prevented?
function _INPUT($name,$tag,$sql,$url)
{
if ($_SERVER['REQUEST_METHOD'] == 'GET')
$filter = ($_GET[$name]);//Assign GET to filter variable
if ($tag == true)//Remove all HTML, PHP and JAVASCRIPT tags
{
$filter = strip_tags($filter);
}
if ($sql == true)//If MYSQL escaping is enabled
{
$filter = mysql_real_escape_string($filter);
}
if ($url == true)//If URL encoding is enabled
{
$filter = urlencode($filter);
}
return $filter;
}
$output = _INPUT('name',true,true,true);
I will be using prepared statements for MYSQL too, although I need to read up on them more to fully understand how it prevents injection.
Thank you for your time.
Once again, there is no universal escape function that just magically makes things "secure".
See this: https://stackoverflow.com/a/7810880/362536
Different escape methods are used for different things. You can't just run a bunch of data through a bunch of functions that are supposed to be used in specific contexts. You are creating garbage data, and are no more secure than you were with the raw user data in the first place.
No,
For SQL Injection prevention, you really want to be using prepared statements. This is a safer way to do this, instead of escaping quotes. You also want to use htmlspecialchars() for escaping HTML tags, instead of just stripping them away, but that's up to you.
This is kind of an eternal question, and the answers vary across wanted usage: for prepared queries, I believe it’s 100 % safe to use its own variables system and let it handle the input. For HTML output, stripping tags may not always be what you want; moreover, it’s kind of safer to do a whitelist of what to allow in input than blacklist, because you know, hackers have fantasy. For URL output, your solution should be fine, but be aware that some other platforms may do a little different URL-encoding (see the difference between a string URL-encoded by Java standard libraries and iOS/Mac libraries, i.e.).

"slash before every quote" problem [duplicate]

This question already has answers here:
Why are $_POST variables getting escaped in PHP?
(6 answers)
Closed 7 years ago.
I have a php page which contains a form.
Sometimes this page is submitted to itself (like when pics are uploaded).
I wouldn't want users to have to fill in every field again and again, so I use this as a value of a text-input inside the form:
value="<?php echo htmlentities(#$_POST['annonsera_headline'],ENT_COMPAT,'UTF-8');?>">
This works, except it adds a "\" sign before every double-quote...
For instance writing 19" wheels gives after page is submitted to itself:
19\" wheels
And if I don't even use htmlentities then everything after the quotes dissappears.
What is the problem here?
UPDATE:
Okay, so the prob is magic_quotes... This is enabled on my server...
Should I disable it? I have root access and it is my server :)
Whats the harm in disabling it?
Looks like you have magic quotes turned on. Use below condition using stripslashes with whatever text you want to process:
if(get_magic_quotes_gpc())
{
$your_text = stripslashes($your_text);
}
Now you can process $your_text variable normally.
Update:
Magic quotes are exaplained here. For well written code there is normally no harm in disabling it.
You likely have magic quotes turned on. You need to stripslashes() it as well.
Nicest way would be to wrap this in a function:
function get_string($array, $index, $default = null) {
if (isset($array[$index]) && strlen($value = trim($array[$index])) > 0) {
return get_magic_quotes_gpc() ? stripslashes($value) : $value;
} else {
return $default;
}
}
Which you can use as
$annonsera_headline = get_string($_POST, 'annonsera_headline');
By the way:
And if I don't even use htmlentities then everything after the quotes dissappears.
It's actually still there in the HTML source, you only don't see it. Do a View Source ;)
Update as per your update: the magic quotes is there to prevent SQL injection attacks in code of beginners. You see this often in 3rd party hosts. If you really know what you're doing in the code, then you can safely turn it off. But if you want to make your code distributable, then you'll really take this into account when gathering request parameters. For this the above function example is perfectly suitable (you only need to write simliar get_boolean(), get_number(), get_array() functions yourself).
Yes, you should disable magic quotes if you can. The feature is deprecated, and will likely go away completely in the future.
If you've relied on magic quotes for escaping data (for instance when inserting it into a database) you will may be opening yourself up to sql injection vulnerabilities if you disable it. You should check all your queries and make sure you're using mysql_real_escape_string().
I include the following file to undo magic quotes in apps that are deployed to servers not under my control.
<?php
set_magic_quotes_runtime(0);
function _remove_magic_quotes(&$input) {
if(is_array($input)) {
foreach(array_keys($input) as $key) _remove_magic_quotes($input[$key]);
}
else $input = stripslashes($input);
}
if(get_magic_quotes_gpc()) {
_remove_magic_quotes($_REQUEST);
_remove_magic_quotes($_GET);
_remove_magic_quotes($_POST);
_remove_magic_quotes($_COOKIE);
}
return true;
?>
This is actually a function of PHP trying to be security conscious, luckily there is an easy fix for it that looks something like this:
if (get_magic_quotes_gpc()) {$var = stripslashes($var);}
There isn't a huge problem in having it enabled, it comes down to personal preference. If you code will be moving servers much and you can't disable it through your php.ini file, it's best to use something as described above.
If you have access to your php.ini file and you want to change it, because you don't want to have to validate it each time you can add the following line to php.ini
magic_quotes_gpc = Off
Or the following to your .htaccess:
php_flag magic_quotes_gpc Off
Hope this helps clear things up.
Looks like your server is setup to use Magic Quotes.
You can fix it by stripping them with stripslashes, or better, by turning off Magic Quotes.
you shouldn't use htmlentities() when writing something to an input field value.
is magic_quotes enabled on your server? try out stripslashes before the output.

Best way to sanitise POST/GET variables from a form/URL? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Best way to stop SQL Injection in PHP
I am creating a website using PHP that makes use of a MySQL database and handles forms and variables from the URL. The variables are being using to dynamically construct SQL query strings. So i need a robust solution to make sure nobody is trying a SQL injection, etc.. A friend of mine has said that really i should only use stored procedures to access the database but that's not really feasible because the host i'm using doesn't allow these.
Here is the code i'm using (it's part of a class to wrap DB commands):
...
public function Sanitize($Variable)
{
if(is_resource($this->ServerConnection))
{
$Variable = str_replace(";", "", $Variable);
if(get_magic_quotes_gpc())
{
if(ini_get('magic_quotes_sybase'))
{
$Variable = str_replace("''", "'", $Variable);
}
else
{
$Variable = stripslashes($Variable);
}
}
return mysql_real_escape_string($Variable, $this->ServerConnection);
}
else
{
$this->PrintError("The Sanitize function is not available as there is no server connection.");
}
}
...
Is this function robust enough? Should i be doing anything else?
Might be worth reading this post.
What is the best way of ...
There is no best way. It depends on the context.
.. sanitising POST/GET variables from ..
It is a flawed mode of thinking that data are good or bad. Data is just data. It's the context in which it's used that makes it malicious or not. Some words may be bad if you execute them unadorned on a database server. Some words are bad if you display them to minors. It's about context.

Categories