PHP deprecated code? - php

HI all
Running PHP Version 5.2.11 and we've been given a site which we're told was running on an earlier version (4 possibly).
We've an odd problem where several pages which have a bunch of forms which update the MySql are not working. The problem is where the variables used in the update script are not being defined anywhere in the php before hand. eg.
UPDATE users SET FirstName='$form_firstname'WHERE UserID='$id'"
Now if we change it to..
$form_firstname = $_POST['form_firstname'];
UPDATE users SET FirstName='$form_firstname'WHERE UserID='$id'"
then the update works. We could do this for every single variable defined in every update statement but I'm thinking that seen as this must have worked previously we're looking at some deprecated code somewhere that forms these variables. I've looked for any
import_request_variables
statements but nada.
Can anyone think of anything that would be turned off by default in a new server that would cause this or does this variable have to be declared somewhere?
Cheers muchly

This is register_globals. DO NOT use this; it is a gaping security hole.

As stated elsewhere, its because the original code was register_globals enabled - which is very bad practice.
As a quick hack you could add some code at the top of each page (in global scope):
extract($_GET); extract($_POST);
...which has much the same effect but on a script-by-script basis. But ONLY to keep the site running while you re-implement the code properly. Note that this is not the only problem with the code - splicing unchecked user input into SQL statements is a recipe for DISASTER.
You should be rewriting the code as....
$form_firstname = mysql_real_escape_string($_POST['form_firstname'], $db_handle);
$id = mysql_real_escape_string($_POST['id'], $db_handle);
$qry="UPDATE users SET FirstName='$form_firstname'WHERE UserID='$id'";
C.

i hope you don't use that for something serious. That code is open to all kinds of intrusions, injections and hacks. I have two answers for you. Quick & dirty: turn register_globals on. Alternative: find someone to rewrite your app from scratch or find a better one.

I think you need set resister_global=on in php.ini

Related

$_POST being automatically copied into other variables

(I apologize for a stupid question. This must be a simple setting, but an hour of Google hasn't revealed it.)
We have a LAMP web server. When we send data through post, the $_POST variable is set as expected. But we also get a global variable for every entry in $_POST.
For instance, if $_POST['Research'] is "Yes", we also get a global $Research set to "Yes".
How do we turn this off?
you have the dangerous and deprecated
register globals on
basic details:
http://php.net/manual/en/faq.using.php#faq.register-globals
to turn off:
http://php.net/manual/en/ini.core.php#ini.register-globals
if your php version is so old that it came with this on by default you should upgrade
Your description sounds like you are using register globals?
If so I am surprised you are still able to as they are deprecated.
You should update your php or at least disable it in your php.ini conf - register_globals=0;

Convert big php project from register_globals to _GET["param"]

I have a rather big php site, which was written for php4 and register_globals enabled. It is old custom CMS. Now I want to run it on the php5 hosting without register_globals. Is it possible to change parameters parsing from $id to $_GET["id"] automatically, with some script?
I can get parameters names from wget -r on this site.
It have dozens of php scripts, and it is not very easy to do this change manually.
PS: UPDATE: I want to convert only GET variables. The additional line is $var_name = $_GET["var_name"] for each parameter. This line should be inserted very high in the script, e.g. by adding a new <? ?> section at very top.
Running such tool would introduce great risk of introducing errors in code.
I'd suggest running extract() on superglobals, so that you force register_globals and aplication will work properly.
http://php.net/manual/pl/function.extract.php
Next, when everything will be ok, write an OO wrapper for input parameters, pack it into nice DI Container and start manually transitioning whole script to the new style.
I don't know of any tools that help you in the conversion, but you have several options:
Simulate register globals by doing the same thing that register_globals did: At the beginning of the script, put all variables from GET and POST into the global variable namespace (i.e. via extract). While this is fastest and the most easy solution, it will lead to the security problems that register_globals was known for, and it doesn't help with the performance of your application
Determine the variables that are used and load them only via the init script into $GLOBALS only. Still not nice
Determine the variables that are used and replace the GLOBALS usage with REQUEST
Walk through it manually. This way, you can be sure everything is correct and will have the least trouble afterwards.
From your description, solution 1 or 2 might be the best for you since the cms doesn't seem to be updated anyway (which is a shame).
Although the actual finding/replacing might take more time, doing this manually will most likely result in less bugs / weird behaviour.
If are not the original author of the application, then this manual finding/replacing is also an opportunity for you to become much more familiar with the codebase than some automatic method.
Automatic: fast, almost definitely will result in some horrible bugs
Manual: slower (likely), almost definitely will result in better understanding, less bugs - and any bugs that are introduced will be easier to fix because of your better understanding.

Include File Vulnerability

I try to read Claroline source code to learn from their coding.
In index.php file, at the first line of code, they write
unset($includePath); // prevent hacking
You can see full claroline source code from here.
They commented that the line is used to prevent hacking..
I have no idea why should they unset $includePath while the variable is never defined before that line..
What is the purpose of that line of code do actually, and what hacking type that they means?
I have not looked at the source myself, but a bit of searches gives the following kind of security advisory :
Claroline mambo.inc.php and postnuke.inc.php "includePath" file include
Note that this relies on register_globals being enabled, which :
is not the default : it's been disabled by default for a very long time (since PHP 4.2.0)
is bad practice (unsafe ^^ as it allows anyone to inject variables into the PHP scripts ; which is why this one, in this case, is unset "to prevent hacking" )
The variable might not be set in code before that point, but if register_globals is turned on, it could be set in the URL by a malicious user.
It sounds like you're mostly looking for educational info, so here's a wee explanation of what register_globals used to do ... why it was there ... and why it's not any more (and you should never turn it on).
Variables come in via the $_GET and $_POST (or $_REQUEST) arrays ... what register_globals did, was make programming easier, by taking all the elements of these arrays, and putting them in the global namespace - i.e., making "regular" global variables out of them - so $_GET['includes'] could very easily be referenced simply as $includes.
This was in the happy days of the intarweb when the internet hadn't proliferated nearly as much as it has now, the technology wasn't so well know, there were fewer people who knew how to hack sites, and no one was writing worms that would automatically hack sites.
It was terribly insecure - because if a lazy programmer hadn't bothered to initialize all variables properly (e.g., checking if $includes is set, and then using it, before it's properly initialized), any of these improperly initialized variables could be set to whatever a hacker wanted. PHP was fairly new then, and many hobbyists were writing code - frequently also doing things like forgetting to properly escape variables in SQL queries. So one security flaw was usually easy to follow up with another one, allowing a hacker (or automated script) to gain deeper and deeper levels of access.
Around 2001 or so, people began very seriously warning about the consequences of register_globals - so this is a rather old issue, but it's still good to be on the lookout, especially with applications that don't have a solid reputation for security.
héhé it's a long story.
In fact in early "naive" version of claroline, Security was not really a target ;-)
$includePath was compute in init to buil all others paths of claroline.
With servers configured with register global=on, it's was a very easy way to hack.
ie : include($includePath."/lib/pager.lib.php");
This simple line was a "patch".
as require '../../../../inc/claro_init_global.inc.php';is included in all.
Conclusion : Claroline is an old code started in php4, with script writed for php3, secure (now) but old. The style is not a good inspiration for "modern" code :-)
Secure claroline was a great adventure -) Mathieu has done most of correction.
I remeber they work more than one month to be comptabile with register global off (I mean it 7y ago)

How to get $_GET variables in PHP

I'm working on application built years ago, that has recently stopped working correctly. Old programmer said, that he might be accessing $_GET or $_POST variables without reading them from $_GET[] array, but through the register_globals
I want to ask: What are different ways to access $_GET variables without using $_GET[] array (e.g. direct ways?) and, if known, how can I check if this application uses any of them?
Thank you in advance
EDIT: The other ways I remembered was register_globals, not magic_quotes. Also, I do not wish to use it, but rather detect if it was used and in latest server update deprecated (what could explain why app stopped working correctly)
EDIT: My english is horrible today. As I explained in one of answers: I need to check, whether original programmer used some obscure and/or deprecated method of getting variables from query string to PHP, so the values application now works with are wrong/not initialized
IMPORTANT EDIT: import_request_variables is off the table, it isn't used. All $_ arrays are off the table too, because latest update wouldn't broke them (=>they still work). How can I detect what variables are initialized with register_globals?
YET ANOTHER EDIT: I found this:
foreach ($_POST as $k => $v) {
eval("\$".$k." = '".$v."';");
}
foreach ($_GET as $k => $v) {
eval("\$".$k." = '".$v."';");
}
Could it have been broken by one of latest updates (max. 1 week ago)?
You mean through Register Globals and not Magic Quotes... BTW Register Globals is pure evil never use them (and they are deprecated as of PHP 5.3.0)!
Edit: If you want to check if the application used Register Globals, try to search for $_GET values as variables. For example for index.php?id=123 try to look for $id in the PHP code. If you find it this does not mean that the script uses Register Globals but if $id comes from nowhere and is never initialized/setted it's a good (bad!) sign that the app uses Register Globals...
$_SERVER["QUERY_STRING"] will give you the raw GET string.
That said, this sounds like a problem that should be fixed at its root, not by using a different variable.
If magic quotes are an issue, do a check for whether they are enabled, and deal with the incoming data accordingly.
The Disabling Magic Quotes page in the PHP manual shows a way to "fix" the incoming data depending on whether the functionality is activated or not. It's not very efficient for huge amounts of data, but should do in an everyday task.
You also have $_REQUEST, magic_quotes (deprecated) would only influence the content of the variables, not the means of capturing them.
Also see import_request_variables, the original coder may have used it to grab the contents of a GET variable and insert it into another variable which is then subsequently being referenced.
Register Globals is a horrible feature that older PHP programs often rely on.
With register globals switched on, PHP will look at the GET and POST variables and "promote" them to normal variable names - eg $_GET['myvar'] would be accessible in the code as $myvar.
Among other issues, this makes the program very easy for hackers to break simply by guessing what other variable names the programmer may have used. The register globals feature has therefore been turned off by default for a long time, is now officially deprecated, and will be removed entirely in a future version.
Because the variables used this way are referenced in a way that is indistinguishable from normal variables, it means that trying to update old code that uses register globals can be very difficult. It does depend a lot on how well written the code is.
The problem is probably PHP's register_globals. This option makes $_GET['some_var'] or their equivalent $_POST version available as $some_var automatically. This is deprecated and you should definitely not use it, but the other programmer might have used them in that application.

How do I execute PHP that is stored in a MySQL database?

I'm trying to write a page that calls PHP that's stored in a MySQL database. The page that is stored in the MySQL database contains PHP (and HTML) code which I want to run on page load.
How could I go about doing this?
You can use the eval command for this. I would recommend against this though, because there's a lot of pitfalls using this approach. Debugging is hard(er), it implies some security risks (bad content in the DB gets executed, uh oh).
See When is eval evil in php? for instance. Google for Eval is Evil, and you'll find a lot of examples why you should find another solution.
Addition: Another good article with some references to exploits is this blogpost. Refers to past vBulletin and phpMyAdmin exploits which were caused by improper Eval usage.
Easy:
$x // your variable with the data from the DB
<?php echo eval("?>".$x."<?") ?>
Let me know, works great for me in MANY applications, can't help but notice that everyone is quick to say how bad it is, but slow to actually help out with a straight answer...
eval() function was covered in other responses here. I agree you should limit use of eval unless it is absolutely needed. Instead of having PHP code in db you could have just a class name that has method called, say, execute(). Whenever you need to run your custom PHP code just instantiate the class of name you just fetched from db and run ->execute() on it. It is much cleaner solution and gives you great field of flexibility and improves site security significantly.
You can look at the eval function in PHP. It allows you to run arbitrary PHP code. It can be a huge security risk, though, and is best avoided.
Have you considered using your Source Control system to store different forks for the various installations (and the modules that differ among them)? That would be one of several best practices for application configuration I can think of. Yours is not an unusual requirement, so it's a problem that's been solved by others in the past; and storing code in a database is one I think you'd have a hard time finding reference to, or being advised as a best practice.
Good thing you posted the clarification. You've probably unintentionally posed an answer in search of a suitable question.
Read php code from database and save to file with unique name and then include file
this easy way for run php code and debug it.
$uniqid="tmp/".date("d-m-Y h-i-s").'_'.$Title."_".uniqid().".php";
$file = fopen($uniqid,"w");
fwrite($file,"<?php \r\n ".$R['Body']);
fclose($file);
// eval($R['Body']);
include $uniqid;
How I did this is to have a field in the database that identified something unique about the block of code needing to be executed. That one word is in the file name of that code. I put the strings together to point to the php file to be included. example:
$lookFor = $row['page'];
include("resources/" . $lookFor . "Codebase.php");
In this way even if a hacker could access you DB he couldn't put malicious code straight in there to be executed. He could perhaps change the reference word, but unless he could actually put a file directly onto the server it would do him no good. If he could put files directly onto the server, you're sunk then anyway if he really wants to be nasty. Just my two cents worth.
And yes, there are reasons you would want to execute stored code, but there are cons.

Categories