This questions is being asked after having read a few others.
Do not access superglobal $_GET array directly
“Do not Access Superglobal $_SERVER Array Directly” on Netbeans 7.4 for PHP
Why is filter_input() incomplete?
I have loaded up the latest version Netbeans 8.0 and I have seen a warning
Do not Access Superglobal $_REQUEST Array Directly.
Great, I am happy to be shown when I am doing something which can be improved upon, so I look at the hints.
The suggestion is quite simple.
Use some filtering functions instead (e.g. filter_input(), conditions
with is_*() functions, etc.).
So I start looking into fliter_input() however it is not yet implemented for $_REQUEST. This seems like a little bit of a dead end.
Then I read something which was quite helpful from (#bobince) "At the start of your script when you're filtering, you don't know where your input is going to end up, so you don't know how to escape it."
It reminded me, I know exactly where my input is going to end up, and exactly what it will be used for. So, I wanted to ask everyone if the approach I am going to take is essentially safe.
I am designing a REST-ish API and I am using $_SERVER['REQUEST_METHOD']; to determine the resource which needs to be returned. I am also using $_REQUEST['resource']; which should contain everything on the URI after /api/ following the .htaccess rewrite.
The questions I have about my approach are:
If I always validate $_SERVER['REQUEST_METHOD']; to be within the required GET PUT POST DELETE (which i will need to do anyway), is there really a problem not filteing the input?
Should I be accessing the $_REQUEST['resource']; by using filter_input (INPUT_GET, 'resource');? When this will only be used to determine a resource, and where the resource can not be determined (say someone attempts to add malicious code) we will simply not find a resource and return a 404 Not Found status.
Are there any other considerations I need to take into account and have I missed anything critical in my understanding?
I realise, this may seem like a lot of concern for what is only considered a warning however, in my experience, fixing just the errors will give you working code, but fixing the warnings will help you understand why the code works.
So I start looking into fliter_input() however it is not yet implemented for $_REQUEST. This seems like a little bit of a dead end.
I'd say it is not a dead end but on purpose. filter_input() requires you to clearly specify the input type. $_REQUEST is not clear about it, it contains input from various sources, allowing one source overwriting another.
Next to that this is also not what the warning precisely wants to tell you. Swapping a superglobal like $_GET with an equally superglobal function like filter_input(INPUT_GET, ...) shows the same design flaw. But Netbeans can't warn you as easily about it.
And getting rid of superglobals is already a good idea.
Instead, inject input data to your application at a low-level place, e.g. bootstrapping the request information and do not use any superglobals nor the filter_input function in the rest of your code.
That will allow you to easily simulate any request method without even having an actual request.
Related
A user reported that changing our post request (directly using live http headers) from notes to notes[] broke our php application and also exposed our full path (error reporting on).
Short of going through our entire application and doing:
if(is_array($_POST['some_param'])) {
die("Invalid parameter");
}
Is there a better way to protect against this type of attack?
Testing for invalid values makes for a nasty game of cat and mouse. Try the opposite pattern where you proceed only on expected types.
In your scenario, test to see if $_POST['some_param'] represents a single text value and only then proceed with processing the request.
Checking the expected type being passed around is the best way to go about it.
http://php.net/manual/en/reserved.variables.post.php
Turning off error reporting in a production environment is always helpful. You can always check your error logs through what ever server you're using (Apache, nginx, etc).
As far as checking all post variables for if they are an array, if you're worried about it, you can always use your included header in all files to just iterate over your _POST variable and clean it up, this is called sanitizing your variables, there are many articles on the internet on how to go about this, here is an article that could help you understand this:
http://www.dreamhost.com/dreamscape/2013/05/22/php-security-user-validation-and-sanitization-for-the-beginner/
Sounds like you use notes in many different places, you don't have a single gateway (eg all routes through index.php), and you want to add some protection.
If so, I suggest using the auto_prepend_file configuration value to load in a script (call it say input-filters.php) that does something like:
$_POST = filter_input_array(INPUT_POST, [ 'notes' => FILTER_REQUIRE_SCALAR ]);
There's tons more you can do with filters, so do check out the examples.
I've never understood this, and on my own projects I have never needed it. But I've been contributing to WordPress a little, and they use it heavily.
Somehow they are able to redirect the user to a different page with some sort of GET variable in the URL (which is what I understand to be the advantage of using GET over POST). How do they do this? Is it as simple as making a header like header('site.com/page.php?foo=true');? This can't be useful since you have to hard code everything in (unless you want to create a string based on other variables which is kind of annoying, even still). I thought there would be a built-in function like send_get('page.php', $foo);.
I understand how to use information by using $foo = $_GET['foo'];, but I don't know how to send it with PHP.
An explanation would be appreciated - thanks!
There isn't exactly a "customary" way of using it. It is one of nine superglobals. The way you use them is at your discretion. As Greg P already mentioned, they are passed through the URL.
I know how to set up a HTML form that sends variables this way, but how can I do the same thing with PHP?
If you're talking about sending GET variables with PHP solely, the answer is no. You needn't even have PHP to send a GET variable. It is as simple as adding a question mark followed by a variable name = something. Separate several of them using an ampersand (&)
Setting up a GET variable is as easy as creating an anchor link.
<a href='somepage.php?getVar1=foo&anotherVariable=2&thirdVar=3
You can use PHP to dynamically place certain information in there instead of writing it manually, which is the entire purpose of the language to begin with. It is a preprocessor
So, something like this should get you started
<?php
$someID = // An id pulled from a mysql_query
echo "<a href='somepage.php?someID=" . $someID . "'>GET LINK</a>";
I thought there would be a built-in function like send_get('page.php', $foo);
Again, PHP is a preprocessor. It doesn't send information, it only outputs it. What you're talking about is Javascript.. moreover, AJAX. AJAX is the only method that will allow you to send GET variables "behind-the-scenes". And, like was mentioned in another post, jQuery has an awesome codebase for this.
I think you're missing the forest for the trees...the $_GET/$_POST are just variables that are passed to the page processing them - what is DONE with them and how it is done, is up to the design of the application. For example, Joomla always puts the component_id and the item_id in the $_GET array, and has been designed with that in mind, so expects them to be there, and constructs the page, or redirects, or whatever with that in mind.
In your example, a send_get() function might be a good idea (I didn't design it), but the architects didn't see it that way for one reason or another. Joomla happens to have a redirect function that does have a certain dependancy on what was passed in the $_GET, but that is only by design of the applications authors.
Maybe redirect URL is kept in some of session variable. Properly $_GET variable, indicate for wordpress: "check session variable for redirect URL".
PHP.net says:
An associative array of variables passed to the current script via the URL parameters.
URL parameters: generally are variables passed to a script via the URL such as in your example site.com/page.php?foo=true. Everything after the ? is considered a paramter.
Quoted from a StackOverflow question:
The HTTP protocol defines GET type requests as being idempotent, while POST may have side effects. In pain English that means that GET is used for viewing something, without changing it, while POST is used for changing something. For example, a search page should use GET, while a form that changes your password should use POST.
I was reading something about SuplerGlobals like $_SERVER or (see more detail PHP Manual Superglobals) the other day, now, I'm asking me:
Is it possible to implement own SuperGlobals?
Beside of Constants...
So for example user A writes something in the Variable which, if User B is calling it can see.
Something like a server wide Session Variable or something.
Please don't be to hard, if its a silly question :)
I know there are couple of ways outside, like SQL, Xml and Stuff, but maybe...
Your whole idea of PHP superglobals it wrong.
These variables are always available in terms of just one script runtime, no the whole site.
PHP doesn't have context which can be shared between users. You should some replacement like SQL server or file. You may also check some extensions like memcache which might help you achieve your goal.
I was reading something about SuplerGlobals like $_SERVER or (see more detail PHP Manual Superglobals) the other day, now, I'm asking me:
Is it possible to implement own SuperGlobals? Beside of Constants...
Yes it is possible if you've got the PHP runkit extension.
So for example user A writes something in the Variable which, if User B is calling it can see
That's not what superglobals do - they are variables which exist in global scope (i.e. for the duration of an instance of a script).
If you want to share data between different invocations then you need to send it to your storage tier or (in the case of data for a single client) out to the browser.
Since what you are describing here is effectively a shared session, then the sensible place to implement this would be in the session handler.
This is not possible, you can only see your own session data.
To achieve this you would need to store the data somewhere else. in text files or in a MySQL database would be the most common.
i suppose you can use (asterix)export yourvar="something"(asterix) and to receive it using getenv
sry, dont know how to embed asterix=`, but it is better to avoid it...
If you use apache following could be used:
http://php.net/manual/en/function.apache-setenv.php
same idea, enveroinment variable
I am trying to trace the flow of execution in some legacy code. We have a report being accessed with
http://site.com/?nq=showreport&action=view
This is the puzzle:
in index.php there is no $_GET['nq'] or $_GET['action'] (and no
$_REQUEST either),
index.php, or any sources it includes, do not include showreport.php,
in .htaccess there is no url-rewriting
yet, showreport.php gets executed.
I have access to cPanel (but no apache config file) on the server and this is live code I cannot take any liberty with.
What could be making this happen? Where should I look?
Update
Funny thing - sent the client a link to this question in a status update to keep him in the loop; minutes latter all access was revoked and client informed me that the project is cancelled. I believe I have taken enough care not to leave any traces to where the code actually is ...
I am relieved this has been taken off me now, but I am also itching to know what it was!
Thank you everybody for your time and help.
There are "a hundreds" ways to parse a URL - in various layers (system, httpd server, CGI script). So it's not possible to answer your question specifically with the information you have got provided.
You leave a quite distinct hint "legacy code". I assume what you mean is, you don't want to fully read the code, understand it even that much to locate the piece of the application in question that is parsing that parameter.
It would be good however if you leave some hints "how legacy" that code is: Age, PHP version targeted etc. This can help.
It was not always that $_GET was used to access these values (same is true for $_REQUEST, they are cousins).
Let's take a look in the PHP 3 manual Mirror:
HTTP_GET_VARS
An associative array of variables passed to the current script via the HTTP GET method.
Is the script making use of this array probably? That's just a guess, this was a valid method to access these parameter for quite some time.
Anyway, this must not be what you search for. There was this often misunderstood and mis-used (literally abused) feature called register globals PHP Manual in PHP. So you might just be searching for $nq.
Next to that, there's always the request uri and apache / environment / cgi variables. See the link to the PHP 3 manual above it lists many of those. Compare this with the current manual to get a broad understanding.
In any case, you might have grep or a multi file search available (Eclipse has a nice build in one if you need to inspect legacy code inside some IDE).
So in the end of the day you might just look for a string like nq, 'nq', "nq" or $nq. Then check what this search brings up. String based search is a good entry into a codebase you don't know at all.
I’d install xdebug and use its function trace to look piece by piece what it is doing.
EDIT:
Okay, just an idea, but... Maybe your application is some kind of include hell like application I’m sometimes forced to mess at work? One file includes another, it includes another and that includes original file again... So maybe your index file includes some file that eventually causes this file to get included?
Another EDIT:
Or, sometimes application devs didn’t know what is a $_GET variable and parsed the urls themselves -> doing manual includes based to based urls.
I don't know how it works, but I know that Wordpress/Silverstipe is using is own url-rewriting to parse url to find posts/tags/etc. So the url parsing maybe done in a PHP script.
Check your config files (php.ini and .htaccess), you may have auto_prepend_file set.
check your crontab, [sorry I don't know where you would find it in cpanel]
- does the script fire at a specific time or can you see it definitely fires only when you request a specific page?
-sean
EDIT:
If crontab is out, take a look at index.php [and it's includes] and look for code that either loops over the url parameters without specifically noting "nq" and anything that might be parsing the query string [probably something like: $_SERVER['QUERY_STRING'] ]
-sean
You should give debug_backtrace() (or debug_print_backtrace() a try. The output is similar to the output of an Exception-stacktrace, thus it should help you to find out, what is called when and from where. If you don't have the possibility to run the application on a local development system, make sure, that nobody else can see the output
Are you sure that you are looking at the right config or server? If you go the url above you get an error page that seems to indicate that the server is actually a microsoft iis server and not an apache one.
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.