Php File function doubts: URL or Path - php

Using the file function, is there any difference in using an URL or a path?
$my_array = file("http://www.mydomain.com/my_script.php?id=1");
$my_array = file($_SERVER['DOCUMENT_ROOT']."my_script.php?id=1");
I'm using the first one, but I guess that it's dependant on my server internet conection because, sometimes, despite the fact that the script is called (I know it because my_script.php inserts a row in the database) I don't get the response and $my_array is empty.
Am I right?
If so, using the second call would fill always $my_array with a response. Won't it?
Can I call a file from a path passing arguments in the same way I would do with the URL?
Edit: Thanks a lot for your answers, and sorry if this question is too stupid.. I'm working on some other guy code. He was doing it this way because my_script.php is also called from other server. I'll try to do it with require preparing firstly the $_GET variable (a bit tricky but I don't want to touch my_script.php).

Any path starting with http://... will make an actual HTTP request. Essentially, it'll do the same as if you typed that URL into your browser. If you're doing this for a script on your own server, it's extreme nonsense because:
it needs to "go out" and establish a TCP connection, to itself
it ties up another web server process
it ramps up another separate PHP process
it doesn't keep the context of the current PHP process
it may not be able to return anything at all, because it will only return whatever the other script echos out
This only ever makes sense if you're trying to communicate with some other remote server.
On the other hand, using ?id=1 on a local, non-http://... file is not possible, since ?id=1 is not a valid part of a file name (or at least it probably doesn't do what you think it does).
What you typically want is something like:
require __DIR__ . '/foo.php';
This includes the other PHP script in your current script as PHP code. You should be defining functions and classes, use autoload to load them and call them as needed, but this is quite a broad topic of proper code organisation I won't go into here.

All file() does is read a file. It's intended to load something from disk, but supports any fopen wrapper PHP provides, such as HTTP.
When you pass a URL to file(), it goes and fetches that URL from your web server. Your web server will execute your PHP and return the result, which is what you get back from file(). So no, what you have there are completely different mainly because one involves the web server and PHP, and the other doesn't.
Don't do it this way. Use require() or require_once() instead.

Related

PHP - Global, Update-Able Variable Available to All Clients

GOAL: To have a global variable that any php on my website can access. The variable would be a bool.
What I am stuck on is how I can store such a variable that is available to all php scripts, but can also be updated via php.
The variable is a bool that determines whether or not the site loads advertisements based off if a certain criteria was met that day. So, every day I will have a cron job that runs to reset this variable, thus meaning the variable needs to be update-able via php.
The only way I can think of to store it is either via a db table, which seems like overkill just for one little bool, or a json file that I store outside of the public_html directory.
With the json file, I would just perform a get on load with file_get_contents via my "class lib" file that is present on all pages of the site. Then do something similar to update it with the cron job.
NOTE: I do have a php file that is present on ALL of my pages, so including a file on every page is not a problem.
Is there a better way? It would be nice if there was a way I could just set a PHP superglobal or something, but I'm unsure if settings something like $_SERVER['custom-variable'] sticks or if it's just for that session.
Apologies if this is a simple mis-understanding of how PHP superglobals/constants work.
I appreciate any help.
A couple of options:
Just store it in the database. This is a perfectly reasonable solution.
Store it in a file, in whatever format you want. JSON is handy if you want to store anything more complex than a single string or number.
Store it in a PHP file which returns a value, e.g.
<?php return array("ads_enabled" => true);
then require() that file -- the require() call will return that value. If your server has a PHP opcode cache enabled, this will be faster than loading a normal file, as the contents of the file will be cached.
Note that the file cannot return false, as that's indistinguishable from the include() failing.
The following are not viable options:
Storing it in a session. Sessions are per-user, and start out empty.
Storing it in an in-memory cache, like APCu or Memcache. Caches are not persistent storage; the value may be evicted from the cache.
Storing it in an environment variable. Environment variables are awkward to update in most server environments.
SetEnv APPLICATION_ENV "development"
Use that in your Apache vhost definition if you are using Apache and have access to modify it. I think you can do something similar in .htaccess files.
You can use a .env file and a library for reading that file.
If you are using a front controller where all requests pass through a single index.php file then you can set a global variable or constant in there.

How to secure sensitive PHP files that process Jquery data?

On my website, I have a search.php page that makes $.get requests to pages like search_data.php and search_user_data.php etc.
The problem is all of these files are located within my public html folder.
Even though someone could browse to www.mysite.com/search_user_data.php, all of the data processed is properly escaped and handled, but on a professional level this is inadequate to even have this file within public reach.
I have tried moving the sensitive files to my web root, however since Jquery is making $.get requests and passing variables in the URL, this doesn't work.
Does anyone know any methods to firmly secure these vulnerable pages?
What you describe is normal.
You have PHP files that are reachable in your www directory so apache (or your favored webserver) can read and process them.
If you move them out you can't reach them anymore so there is no real option of that sort.
After all your PHP files for AJAX are just regular php files, likely your other project also contains php files. Right ? They are not more or less at risk than any script on your server.
Make sure you program "clean". Think about evil requests when writing your php functions, not after writing them.
As you already did: correctly quote all incoming input that might hit a database or sensitive function.
You can add security checks on your incoming values and create an automated email if you detect someone trying evil stuff. So you'll likely receive a warning in such cases.
But on the downside: You'll regularly receive warnings because some companies automatically scan websites for possible bugs. So you will receive a warning on such scans as well.
On top of writing your code as "secure" as you can, you may want to add a referer check in your code. That means your PHP file will only react if your website was given as referer when accessing it. That's enough to block 80% of the kids out there.
But on the downside: a few internet users do not send a referer at all, some proxies filter that. (I personally would ignore them, half the (www) internet breaks on them anyway)
One more layer of protection can be added by htaccess, you can do most within PHP but it might still be of interest for you: http://httpd.apache.org/docs/2.0/howto/htaccess.html
You can store a uid each time your page is loaded and store it in $_SESSION['uid']. You give this uid to javascript by doing :
var uid = <?php print $_SESSION['uid']; ?>;
Then you pass it with your get request, compare it to your $_SESSION :
if($_GET['uid'] != $_SESSION['uid']) // Stop with an error message or send a forbidden header.
If it's ok, do what you need.
It's not perfect since someone can request search.php and get the current uid, and then request the other pages, but it may be the best possible solution.

PHP Get Cookie by Session ID (or otherwise pass data between two different connections)

Normally I try to format my question as a basic question and then explain my situation, but the solution I'm looking for might be the wrong one altogether, so here's the problem:
I'm building a catalog application for an auction website that has the ability to save individual lots. So far this has worked great by simply creating a cookie with a comma-separated list of IDs for those lots, via something like this:
$_COOKIE["MyLots_$AuctionId"] = implode(",",$arrayOfIds);
The problem I'm now hitting is that when I go to print the lots, I'm using wkhtmltopdf through the command-line to request the url of the printout I want, like this:
exec("wkhtmltopdf '$urlofmylots' filename.pdf");
The problem is that I can't pass a cookie to this call, because Apache sees an internal request, not the request of the user. I tried putting it in the get string, but once I have more than a pre-set limit for GET parameters, that value disappears from the $_GET array on the target url. I can't seem to find a way to send POST data between them. My next possible ideas are the following:
Maybe just pass the sessionID to the url, and see if there's a way that I can use PHP to dig through the cookies for that session and pull the right cookie, but that sounds like it'd be risky security-wise for a PHP server to allow (letting one session be aware of another). Example:
exec("wkhtmltopdf '$urlofmylots?sessionId=$sessionIdFromThisRequest' filename.pdf");
Possibly set a session variable and then pass that session Id, and see if I can use PHP to wade through that information instead (rather than using the cookie).
Would I be able to just create an array and somehow have that other script be aware of it, possibly by including it? That doesn't really solve the problem of wkhtmltopdf expecting a web-facing address as its first parameter.
(not really an idea, but some reasoning) In other instances of using this, I've just passed an ID to the script that generates the markup for wkhtmltopdf to parse, and the script uses that ID to get data from the database. I don't want to store this data in a file or the database for the simple purpose of transferring data from the caller to the callee in this case. Cookies and sessions seem cleaner since apache/php handle memory allocation for these sessions.
The ultimate problem here is that I'm trying to get my second script (referenced here by $urlofmylots) to be aware of data available to the calling script but it's being executed as if it were an external web request, not two php scripts being called from the web root.
Can anyone offer some insight here?
You might consider rendering whatever the output of $urlofmylots?lots=$lots_to_print would be to a temporary file and running wkhtmltopdf against that file.

No require, no include, no url rewriting, yet the script is executed without being in the url

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.

Include file_exists safety

/* define page path */
define("PAGE_DIR", "pages/");
if (file_exists(PAGE_DIR."$_GET[page].php")) include(PAGE_DIR."$_GET[page].php");
How safe is this? Could you for example include a page on another webserver if the page is in a folder called pages?
Thanks
This isn't safe at all - Think about what happens if $_GET[page] contains ../../../somewhere/else/
You should explicitly have a list of allowed pages.
Edit: I don't think it could include a file from a different server, but it's still not a good thing to be doing.
It's never good practice to pass unsanitized user input directly to a command, especially something like include(). You don't necessarily know how the underlying webserver/OS is going to handle, for example, relative paths, extended characters, etc. Any of these, used maliciously or otherwise, could result in the user seeing something they're not supposed to see.
One possible exploit: user passes in the relative path to a malicious script in a known location on the server. http://webserver/yourscript.php?page=%2e%2e%2f%2e%2e%2f%2e%2e%2fhome/bad_user/evil_script
which your function could translate to pages/../../../home/bad_user/evil_script.php, which include will happily include, sometimes. So your web page when served could very well execute bad_user's php script, which he could use to do all kinds of nasty stuff.
At the very least you should assign $_GET['path'] to a new variable and addslashes().
Doing anything with $_GET or $_POST prior to validating/sanitizing the data is dangerous. Assume that all users are out to get you, and sanitize the data prior to using it.

Categories