I am writing a series of functions to interact with third-party APIs that will be included in other PHP scripts. Most of these third-party APIs use token-based authentication, so I would like to store these tokens within the function, but I’m wondering what the best practices are for preventing exploitation of those functions in the included file.
For example, in a script called ~/public_html/includes/functions.php I would define some functions that call a public API using cURL, and then return some sort of response from the API. Then, within my app, I would include ~/public_html/includes/functions.php and call the functions to interact with the third-party APIs.
My concern is what if someone else includes http://www.example.com/includes/functions.php in their script, and starts calling my functions to make API calls using my credentials? Should functions.php live somewhere else, perhaps outside of the ~/public_html dir? Or perhaps I can use UNIX permissions to prevent anyone but my own apps to include the functions.php script?
My concern is what if someone else includes
http://www.example.com/includes/functions.php in their script, and
starts calling my functions to make API calls using my credentials?
Should functions.php live somewhere else, perhaps outside of the
~/public_html dir? Or perhaps I can use UNIX permissions to prevent
anyone but my own apps to include the functions.php script?
You are mixing up a lot of things here. And the long story short: You should not worry. I gave a full explanation on how include works with URLs in this answer. Below is a summary for your purposes.
Specifically, while one could use include to include full URLs like include('http://www.google.com/'); the only thing you get from that include is the final rendered content of the page. 100% none of the functions, classes, variables, strings, constants or anything contained in the internals of that PHP code. Or as very clearly explained in the PHP documentation you are linking to; emphasis mine:
If "URL include wrappers" are enabled in PHP, you can specify the file
to be included using a URL (via HTTP or other supported wrapper - see
Supported Protocols and Wrappers for a list of protocols) instead of a
local pathname. If the target server interprets the target file as PHP
code, variables may be passed to the included file using a URL request
string as used with HTTP GET. This is not strictly speaking the same
thing as including the file and having it inherit the parent file's
variable scope; the script is actually being run on the remote server
and the result is then being included into the local script.
So you cannot include credentials remotely—or any PHP internals—in the way you describe. The only way that could happen is if ~/public_html/includes/functions.php were included locally. That is when PHP internals are exposed.
Or the better way to understand this: When you request a PHP file via http:// or https:// it is parsed & processed via the PHP module in Apache. So it only returns the final product—if any—post often conveyed by an echo statement.
But when you include a file via the local file system it is not parsed by the PHP module in Apache. It is simply raw code. And that is how you can use the functions, classes, variables, strings, constants and anything contained in the internals of that PHP code.
Related
I am currently writing my own server in C++ for Posix systems. Before anyone says anything about how I should really use a prebuilt server, please be aware that I do use prebuilt servers for anything business related. This project is entirely a learning experience.
I would like this system to support server side scripting as well as static hosting. I run into a problem when I try to include support for the most important server side scripting language: PHP.
Standard PHP provides several predefined variables that give access to information about an incoming request. It also provides standard HTTP functions that interact with the request in specific ways. Further, it is supposed to be possible to perform IO operations on the request and response bodies by using the filenames php://input and php://output respectively to refer to the appropriate socket and permissions.
I know that I would be able to define all these variables and implement all these functions myself in the top of a wrapper script and then use include to run the user's script in the same context, but that seems cumbersome. I also have no idea how to map php://input or php://output to the actual request socket's file descriptor.
I don't know much about PHP interpreters. Is there a way to provide essential request data (user-agent, INET address, method, URI, version, headers, socket file descriptor, and maybe something I'm forgetting) to the PHP interpreter to be able to access the native definitions and implementations of these variables and functions? Or is it standard practice for the author of the server to define and implement these himself?
Most important, if I do have to implement these things myself, how do I map php://input and php://output to the correct file descriptor and permissions?
Thanks to everyone. Any help is appreciated.
I'm trying to figure out how (if possible) to do this:
I want to have a server/space/cloud-storage without apache storing a php file, then, another server actually running and parsing that file.
This is because I know Dropbox (Copy, Google Deive, etc) does store any type of file but cannot run php files due to security and due to the lack of Apache.
I therefore thought it may be possible to have a server requesting the Dropbox php file, parse it and return the HTML result.
I thought of this solution and I tried making an include from an external source:
include_once("https://dropbox.com/whatever/file.php");
But is not feasible... Any solution?
Use the API of Dropbox instead of the webview. Then store the value in a variable or temp file and output the result of eval($codeFromDropbox); and delete it if you don't need it anymore.
Dropbox provides you a PHP class (also see the reference) to archive this or you can simply use the global HTTP API Docs to write this small script on your own.
Once you did the authorization as described in the API docs you can simply download any file you have the permissions for.
You can actually include remote files but it is disabled by default:
http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
ini_set('allow_url_fopen', true);
This is OFF (false) by default because it is a VERY HIGH security risk.
It's also a high security risk using eval(). The whole idea is risky.
Why don't you store and the files on the PHP server you want to execute?
Update:
The ini configuration is allow_url_include, not allow_url_fopen, but you should lookup both.
I'm not sure it is possible or not, but i try
include "http://www.abc.cm.my/function.php" inside my php file and it not work.
my ideal is
i have a standard function file at my own website and all my clients web will include my standard function directly from my own website, then i no need to duplicate the function file to all my clients website, the trouble i facing now is, i need to change/update the function file at each/all of my clients website, it not hard but just many work to do.
hope you guys understand my situation and my English.
PHP allows for this under certain conditions:
... URLs can be used with the include, include_once, require and
require_once statements (since PHP 5.2.0, allow_url_include must be
enabled for these) ...
Doc
Sure, you can use the URL include wrappers option in PHP on website1. You'll need to make sure that the remote server (website2) is serving the raw PHP--so that when you open it in a browser at http://website1/script.php you see the plain PHP source code.
However this is generally a bad idea, since you normally only want the PHP to be visible server-side (normally you don't want to show your raw code to the world). You could use network mappings / mounts to map the remote filesystem to a local drive, or it would be a bit better if website2 were only a LAN only visible to website1.
I've been using HTTP authentication through .htaccess files every time I've needed quick and dirty password protection for a complete directory (most of the times, in order to hide third-party apps I install for private use). Now I've written some PHP code to replace local passwords with OpenID. That allows me to get rid of HTTP auth in my PHP sites. However, I'm still trying to figure out a trick I can use in non-PHP stuff (from third-party programs to random stuff).
Apache does not seem to support authentication with custom scripts by default (whatever I do, it should work in my hosting provider). That leaves the obvious solution of using mod_rewrite to route everything though a PHP script that checks credentials and reads the target file but 1) it looks like a performance killer 2) it will interfere with dynamic stuff, such as other PHP scripts.
I'm wondering whether there's a way to tune up the router approach so the script does not need to send the file, or if I'm overlooking some other approach. Any idea?
I think your mod_rewrite approach would be the only way to do this - but instead of using readfile() (as I guess you are, based on what you say about it will interfere with dynamic stuff, such as other PHP scripts) you can just include() them, so that raw files are written straight to output and PHP code is executed.
You may use PHP HTTP-AUTH http://php.net/manual/en/features.http-auth.php
If OpenID is all what you need consider usage of mod_auth_openid for apache
I have two PHP web applications. All of the apps are located on the same computer. Each application will run independently.
Now, can I do a direct API call from one PHP app to another? I don't want to go through either the webservice, or the usual HTTP call that involves HTML response. I want to call app A from app B, using direct method call, as if those two apps are the same application.
How to do this?
Usually, you'd use require or include to include the code from one PHP script in another.
If you hadn't done this before, or designed it in, you'll probably need to extract the functions from your script(s), place them in a central file, and include that in all scripts that need it (including, of course, the one they were originally in!). Remember that includeing a file in another causes its embedded HTML to be included too, so you'll typically include PHP files that have functions only, to achieve what you're asking.
Then you just call the function, as if it were written in the script in the first place :)
Try using the system function.
<?php system("php /path/to/other/php/script.php"); ?>