Christian
Christian

Reputation: 28124

Using eval() to enhance security

I admit the title is mostly a catch 22, but it's entirely relevant, so please bear with me for a while...

Background

As some may know, I'm working on a PHP framework whose major selling point is that of bridging functionality between different CMSes/systems. From a developer perspective, there's an extensive error handling and logging mechanism. Right now, there are two settings, DEBUG_MODE and DEBUG_VERBOSE, which control debug output.

The mode describes the medium and verbose controls the amount of detail. To make it short, there's a mode called "console" which basically dumps debug info into the javascript console (which is now available in a major web browser near you).

The Issue

This [debug system] works great for development servers, but you absolutely cannot use it on a production one since debug details (which include DB credentials etc) get published publicly. And in all honesty, who ever migrated from a dev. to a prod. server flawlessly each time?

Solutions

Therefore, I've been trying to figure out a way to fix this. Among my proposed solutions are:

So, do you think eval() should be up to it? I'll ensure it still performs well by only doing this once per page load/request.

Clarification

if(DEBUG_MODE!='none')echo 'Debug'; // this is how it is now
if(DEBUG_MODE!='none' && $USER_CONDITION)echo 'Debug'; // this is how it should be

The $USER_CONDITON allows stuff such as running is_admin() to allow all admins to see debug info, or, getUser()->id==45 to enable it for a specific user. Or by IP, or whatever.

enter image description here

Upvotes: 1

Views: 430

Answers (4)

bob-the-destroyer
bob-the-destroyer

Reputation: 3154

Having a setting which contains PHP expression(code) that gets eval'd and it's return used as a yes/no. The best part is that the framework installed may suggest CMS-specific expressions, eg:

eval() may crash your page if any function doesn't exist or on any number of parse errors. And if bugs exist which allow user-supplied input (such as a uri requested) to even touch these evaled values, it will potentially open up your site to malicious or accidental destruction. Instead to identify the currently working framework, look for markers in the framework you're trying to bridge to, such as certain constants, functions, classes, etc. You can replace all your eval() functions with safe checks using function_exists(), defined(), etc.

Upvotes: 0

mario
mario

Reputation: 145482

Go ahead. It's evident that you understand the hypothetical security implications. In your case it's just important to tell the target user base about it.

As for the practicability of your approach, there's no discussion really. You need variable authentication logic and can't hardwire it to one specific environment/cms runtime.

The only concern you see is about performance. That's baloney. Not an issue. The presence of eval is what discerns scripting languages from compiled languages. If it's available you can not only use it, but can be sure that it's not going to be slow because a compiler+linker run is required behind the scenes. PHP takes some time with initializing its tokenizer and parser, but parsing itself is surprisingly quick.

And lastly, avoid such question titles on SO. ;} Or at the very least talk about create_function please.

Upvotes: 3

Pekka
Pekka

Reputation: 449475

Allowing free-form input of PHP code that gets executed - be it through eval() or create_function() - is simply bad design, and opens a big potential vulnerability for no good reason. It also opens the possibility of crashing a page through syntax errors.

Even the argument that the administrator can install plugins anyway doesn't hold entirely, because XSRF attacks are conceivable that manage to get malicious stuff into a text field (one request), but can't trigger a plug-in installation.

So no, I wouldn't do it; I would implement each CMS bridge as an adapter instead, and let the user choose the adapter (and if necessary enter some custom, sanitizable settings) from a pre-defined list. (Something similar was also suggested by @Wrikken in the comments)

It's your call. Chances are you will never have a problem from doing this the eval() way. And it can be argued that most of the CMSs you will be connecting with (Wordpress, Joomla) allow arbitrary execution of PHP code in the back-end anyway. But it's not good design.

Upvotes: 2

preinheimer
preinheimer

Reputation: 3722

IP spoofing long enough to actually get a response is unlikely to occur. If a user manages to build up a connection to your server, spoofing an internal or privileged developer IP they control your router, so you've got other things to worry about.

Rather than running eval can't you just write an anonymous function/closure: http://php.net/manual/en/functions.anonymous.php (putting it in a config file, rather than web screen, writing complicated PHP code on a web form seems sub-optimal anyways)

Upvotes: 2

Related Questions