Using eval() to enhance security - php

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:
Having a setting which tells the framework to enable logging only if the request comes from a certain IP. The security issues for this are quite obvious (IP spoofing among others).
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:
Wordpress: current_user_can('manage_options')
Joomla: $user=&JFactory::getUser() && ($user->usertype=='Super Administrator') || ($user->usertype=='Administrator')
Custom: $_SERVER['REMOTE_ADDR']=='123.124.125.126'
These are among the two, I'm eager to hear out more suggestions.
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.

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.

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)

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.

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.

Related

Detect if there was an sql injection attack by parsing access logs or HTTP params. PHP Websites

As most programmers I try to program my applications in the safest way possible but this we know that does not guarantee security at 100%. Therefore I think it is also appropriate to have methods to monitor if we may be being attacked. So this is my question.
(My websites are made with PHP and MySQL)
In the case of SQL injection I think this can be done in two ways, but if there are other ways I would also like to know them.
Parsing access/error logs. Does anyone have or know a script that adequately analyzes the access logs (apache) to detect possible attacks? And notify to the administrator automatically with all details.
Analyze HTTP params at real time. It would be a script that analyzes in real time the content passed by GET / POSt and notify (e.g. via email) to the administrator of the website
For example, I do not know much about SQLi attacks but I think it's common for the 'SELECT', 'UINON',...(Others?) strings to appear in query strings and params.
In this way we can analyze the attack and see if it succeeds or not, and then take the consequent actions.
Thanks for your attention!
Edited: Simple bash script
I have made a simple system for analyzing the Apache access_log files and communicate results by email. Which is detailed in this question:
Linux bash to iterate over apache access_log files and send mail
In addition, another one using AWK. The only one resource I've found related about that:
https://www.unix.com/shell-programming-and-scripting/248420-sql-injection-detection.html
(But I have not been able to make it runs in my case)
Oh boy.
Alright, where to start?
For starters, remember that bad hackers are usually financially motivated. You know your website has been injected if you wake up one morning to a red error message from Chrome or Firefox, and you open it anyway to find that your website is now among the more popular places to find free cruises and viagra online.
Sites that score well with SEO are more likely to be hacked than sites that do not. More users means more exposure. Password protected sites don't get hacked as often, but the password protection itself does not necessarily mean any added security. If you're vulnerable, you're vulnerable, and you need to be on top of it.
First and foremost, remember to filter your variables. Never trust anything that comes in from a browser. IT'S ALL SUSPECT. That's means filtering anything that counts as a super global, GET POST, REQUEST, etc. I wouldn't even trust sessions, honestly. Filter it all. More on this can be found here: http://php.net/manual/en/function.filter-var.php
Something else to think about is file uploading. Bad guys love uploading files, and taking over your server. Most common method is exploit files disguised as images. You're going to want to resample every image that comes in. GD Works, but I like Imagick better, personally, more options. More on that here: http://php.net/manual/en/book.imagick.php You're also going to want to make sure that your site can't upload images or any other type of file from pages that you don't explicitly designate as form or upload pages. You would be shocked how often I see sites that can upload from the index, it's insane.
Another method you can deploy for this, is use your php ini to set a global include, and open up any file in a $_FILES array that comes in. Open up the first million spaces in the file, and scan it for php reserved words, and unix shell scripting. If you find one, kill the upload, exit or die, whatever you like to do there.
Apache has a setting for forensic logs. Forensic logs will capture all GET and POST stuff, but the issue with it, and the reason it's not exposed by default is that your log get big, and quickly. You can read up on it here: https://httpd.apache.org/docs/2.4/mod/mod_log_forensic.html
Lastly, you're going to want to evaluate your site for injection vulnerabilities and cross site scripting. Cross site scripting isn't the issue it once was, given the way browsers are constructed these days. All those little details that make life harder for us as a developers actually make us more secure.
But you do want to check for SQL vulnerabilities, especially if you're writing code from scratch. There are a couple reasonably solid plugins for Chrome that make pen testing a little easier.
Hackbar: https://chrome.google.com/webstore/detail/hackbar/ejljggkpbkchhfcplgpaegmbfhenekdc?utm_source=chrome-ntp-icon
HackTab:
https://chrome.google.com/webstore/detail/hack-tab-web-security-tes/nipgnhajbnocidffkedmkbclbihbalag?utm_source=chrome-ntp-icon
For Firefox, there's scrippy
https://addons.mozilla.org/en-US/firefox/addon/scrippy/?src=search
Hope that helps.
Good luck.
Therefore I think it is also appropriate to have methods to monitor if we may be being attacked.
The biggest waste of time ever.
ANY site gets "attacked" 100% of time. There are freely avalable scripts that allow any stupid schoolboy to scan whole internet, probing sites just by chance. You'll grow bored the very next day after scouring these logs of your detection system.
In your place I would invest in the protection. Other vectors than you could think of. For examle, all recent breakings I was a vitness of were performed by means of stealing ftp passwords stored on the webmaster's PC. And I can assure you that there are much more attack vectors than a blunt SQL injection. Which is a simplest thing to protect from, with only two simple rules to follow:
Any variable data literal (i.e. a string or a number) should be substituted with a parameter, whereas actual value should be sent to the query separately, through bind/execute process.
All other query parts that happen to be added through a variable, should be explicitly filtered through a hardcoded list of allowed values.

Server side execution of user submitted code

Here is my situation. I am building an application that contains some heavy mathematical calculations where the formula needs to be editable by a sufficiently privileged, but untrusted, user.
I need a secure server side scripting language. I need to be able to access constants and values from 4+ database tables, the results of previous calculations, define user variables and functions, use if/then/else statements, and I'm sure more that I can't think of right now.
Some options I've considered:
I have considered using something like this matheval library but I would end up needing to extend it considerably for my use case. I would essentially be creating my own custom language.
PHP runkit sandbox. I've never used this before but am very concerned about the security issues involved. Considering the possible security issues, I don't think that this is a viable option.
One other idea that has crossed my mind that I don't know if it is possible would be to use something like javascript on the server side. I've seen js used as a scripting platform in desktop applications to extend functionality and it seems a similar approach may be feasible. I could ideally define the environment that things ran it, such as disabling filesystem access etc. Again, security seems like it would be an issue.
From the research I have done, it seems like #1 is probably my only option, but I thought I would check with a larger talent pool. :-)
If #3 is possible, it seems that it would be the way to go, but I can't seem to turn up anything that is helpful. On the other hand, there may not be much difference between #2 and #3.
Performance is another consideration. There will be roughly 65 some odd formulas each executing about 450 times. Each formula will have access to approximately 15 unique variables a hundred or so constants, and the results of previous formulas. (Yes, there is a specific order of execution.)
I can work with an asynchronous approach to calculation where the calculation would be initiated by a user event and stored in the db, but would prefer to not have to.
What is the best way to work with this situation? Are there any other third party libraries that I haven't turned up in my research? Is there another option in addition to my 3 that I should consider?
There's almost no reason to create a custom language today. There's so many available and hackable, writing your own is really a waste of time.
If you're not serving a zillion users (for assorted values of a zillion), most any modern scripting language is securable, especially if you're willing to take draconian measures to do so (such as completely eliminating I/O and system interfaces).
JavaScript is a valid option. Its straightforward to create mini-sandboxes within JS itself to run foreign code. If you want folks to be able to persist state across runs, simply require them store it in "JSON-like" JS structures that can be readily serialized from the system on exit, and just as easily reloaded. These can even be the results of the function.
If there's a function or routine you don't want them to use, you can un-define it before firing off of the foreign code. Don't want them using "read" to read a file? read = func(s) { }
Obviously you should talk to the mailing lists of the JS implementation you want to use to get some tips for better securing it.
But JS has good support, well documented, and the interpreters are really accessible.
You have two basic choices:
a) Provide your own language in which you completely control what is done,
so nothing bad can happen,
b) Use some other execution engine, and check everything it does to verify nothing bad happens.
My problem with b) is it is pretty hard to figure out all the bad things somebody might do in obscure ways.
I prefer a), because you only have to give them the ability to do what you allow.
If you have a rather simple set of formulas you want to process, it is actually pretty easy to write a parser/evaluator. See Is there an alternative for flex/bison that is usable on 8-bit embedded systems?
It isn't clear to me that you have a performance problem. yes, you want to execute something 450 times; but it includes database accesses, whose cost will dominate any computation involivng a 1000 arithmetic steps. You may find that your speed is limited by the DB access that that you need to cache the DB accesses to get it to go faster.

A secure method for premium php cms

Ok, I am in the process of creating a cms. There will be a free version, and a premium version. Obviously the premium version will have modules and such that the free version does not have. Does anyone have an idea on how i can prevent my premium version from being shared across the web? Ive looked into using a license key with remote server validation, as well as encrytion, and encoding the premium scripts. I dont want to use Zend Guard or Ioncube, because i dont want users to have to have that software installed just to ues the cms. I also want the cms to be customizable which rules out encoding. Anyone have ideas to prevent the scripts from being nulled? If its possible to maybe just encode a single page that does remote validation... just something... It doesnt have to be a bullet proof thing.. but something that prevents novice crackers from nulling it and releasing it
ENCODING PAGES:
Personally, I have tried a few techniques to avoid PHP encoders but nothing was really effective in a commercial environment.
Based on my experience though, I wouldn't worry so much about Ioncube and Zend not being installed on servers because most managed environments will most likely already have both, this is what I have found anyway. Because of this it reduces the problem of users to have to install it for a single application.
In saying that it depends on your target market also, if you're going head-to-head with the likes of Joomla! or WordPress for example, then your target market typically uses a managed environment so no big issue.
If you're however going for say an intranet market this could be a minor problem but any server admin worth a grain of salt will be able to install this easily without fuss, they will also understand why you put it in place. Note, the intranet market is a bit harder as you will need to specify port settings to check the license in your licensing module.
SIDE NOTE: As your product is going to be distributed with source code available you do need to be careful and pay attention to your Intellectual Property (IP), this generally means putting a legal disclaimer on every page that is readable. Also, don't forget to respect the requirements of other IP owners scripts you may be using in your project.
LICENSING & ENCODING (THE SUGGESTION):
Encoding a single page with licensing functions is a way of going about it but you will find it fairly easy to bypass if the rest of the source code is available.
What I would look at is encoding a single page with licensing functions but also encoding your login validation, half of your authentication checks for each protected page and some basic functions for posting to the database also. This way if they try to remove your encoded page with the licensing script there is no login or updating of content - plus they will get kicked out of the system as only half of your session checking will be valid - I hide a kill function nested into another function that is required for each page to operate, this may be a menu (this is great because you can hide the function with the logout), it just looks like part of the log-out function but in reality it is a function to destroy the session if not all variables are present.
When choosing values for your authentication checks on each protected page (that function should be encoded), try using what appears to be a random variable and non-descriptive names then encode the variable (I like MD5 hashes for this). It is another way to give more security around the 'hacking' of your script.
I hope this may help you and sorry that I cannot recommend a better solution.

Security precautions and techniques for a User-submitted Code Demo Area

Maybe this isn't really feasible. But basically, I've been developing a snippet-sharing website and I would like it to have a 'live demo area'.
For example, you're browsing some snippets and click the Demo button. A new window pops up which executes the web code.
I understand there are a gazillion security risks involved in doing this - XSS, tags, nasty malware/drive by downloads, pr0n, etc. etc. etc.
The community would be able to flag submissions that are blatantly naughty but obviously some would go undetected (and, in many cases, someone would have to fall victim to discover whatever nasty thing was submitted).
So I need to know:
What should I do - security wise - to make sure that users can submit code, but that nothing malicious can be run - or executed offsite, etc?
For your information my site is powered by PHP using CodeIgniter.
Jack
As Frank pointed out, if you want to maintain a high level of security use a whitelist technique. This of course comes with a price (might be too restrictive, hard to implement).
The alternative route is to develop a blacklist technique. i.e. only allow code that hasn't triggered any bells. This is easier, because you have to specify less things, but it will not catch new exploits.
There is plenty information available on the web on both techniques.
Relying on CodeIgniters security functions (XSS filtering etc.) will not get you very far as most of the snippets will not be allowed through.
Whatever you do you have to remember this:
Do not think malicious code will aim to just harm your website's visitors. It may as well aim to compromise your server via your parser/code inspector. For example, lets say Alice uploads snippet foo. Alice intentionally crafts the snippet so that your parser will flag it as malicious due to an XSS exploit. Lets say your parser also updates a database with the malicious snippet for further investigation. Alice knows this. Along with the XSS exploit Alice has injected some SQL code in the snippet, so that when you INSERT the snippet to the database it will do all sorts of bad stuff.
If you are really paranoid, you could have an isolated server which its solely responsibility would be to inspect code snippets. So in the WCS only that low-risk server would be compromised, and you would have (hopefully) enough time to fix/audit the situation.
Hope this helps.
You cannot whitelist or blacklist PHP, it just doesn't work. If you write up a list of commands that I can use, or stop me from using malicious functions, what is to stop me from writing:
$a = 'mai';
{$a .'l'}('somebody#important.com', 'You suck', 'A dodgy message sent from your server');
You cannot whitelist or blacklist PHP.
For your information my site is powered by PHP using CodeIgniter
Sorry Jack, if you think that is in the least bit relevant you're a very long way from understanding any valid answer to the question - let alone being able to distinguish the invalid ones.
Any sandbox you create which will prevent someone from attacking your machine or your customers will be so restrictive that your clients will not be able to do much more than 'print'.
You'd need to run a CLI version of suhosin on a custom chroot jail - and maintianing seperate environments for every script would be totally impractical.
C.
Assuming you are only allowing javascript code, then you should do the following -
Purchase a throw-away domain name that is not identifiable with your domain
Serve the user-entered code in an iframe that is hosted from the throw-away domain
This is essentially what iGoogle does. It prevents XSS because you are using a different domain. The only loophole I am aware of is that evil code can change the location of the webpage.
If you intend to share snippets of server side code, then it is a different ballgame. For java/jsp snippets, you could use JVMs internal Security classes to run the code in a sandbox. You should find a lot of information on this if you google. I would like to think this is what google uses in App Engine (I am not sure though).
Anything other than Java, I am not sure how to protect. Dot Net perhaps has a similar concept, but I doubt you could sandbox PHP code snippets in a similar manner.

Interpret text input as PHP

I want to let users test out a PHP class of mine, that among other things crops and resizes images.
I want them to write PHP code in a text field, send the form, and then their code will be run. How can I do this?
Or is it other safe ways to let users (anyone) demo a PHP class?
I would spawn the PHP process using a user account with next-to-no permissions. Give the read-write access to a single directory, but that's it.
You're still opening yourself to DoS attacks with infinite loops and such, but if you absolutely must do it, then run the code in this very-low-permissions sandbox like IE and Chrome do.
Using EVAL is probably the worst idea.
Yes. You can use the eval statement in php (linked earlier by John http://us2.php.net/manual/en/function.eval.php), however be very careful. You really don't want users to be able to run code on your machine freely.
My recommendation would try to come up with a different approach to do demos - perhaps a flexible few examples... but don't let them run code directly
You could use the eval() function, but don't do it. Seriously.
There's no "safe" way to let any old user run their own PHP on your server. You are exposing yourself to a potential world of hurt.
Instead, provide excellent documentation, code samples, and the source for your own demos, and encourage potential users try it out on their own test/development servers.
As it was already stated, you could use eval function, but it's very dangerous. If you want users to test the code, prepare demo pages presenting possible usage, and for instance possibility to add parameters by user via HTML forms.
You could possibly use eval http://us2.php.net/manual/en/function.eval.php
Don't think in terms of PHP or another general-purpose language, think of the minimal language that's sufficient to express the operations in your domain of image processing. Users submit expressions in this domain-specific language (DSL), these expressions are parsed on the server side and passed to your code.
The important thing initially is to think about the range of image-processing operations and how they can be combined. That will tell you how expressive the language has to be. Once you've worked that out, there are plenty of choices for how the language would look syntactically. The syntax of the language might depend on a tradeoff between ease of use and ease of parsing.
If you can write or find a parser for expressions of this kind, it might be the easiest for users. Actually, can anyone recommend an existing expression evaluator that would work in cases like this (for example, can Smarty safely run user-submitted expressions?), or indeed a parser generator for PHP?
resize(rotate("foo.png", 90), 50)
A language like this might be less easy for users, but it can be processed using a fairly simple stack machine:
"foo.png" 90 rotate 50 resize
Even easier, an XML-based language like this doesn't need its own parser:
<resize percent="50"><rotate degrees="90"><img src="foo.png"></rotate></resize>
Using a DSL doesn't protect you from domain-specific attacks, for example somebody might use the language above to resize an image to a zillion pixels and use up all the server memory. So there would have to be some sort of runtime environment for the DSL that puts limits on the amount of resources any user-submitted script can use.
You can use eval, but not without some precautions.
If your security concerns are merely "cautious" as opposed to "paranoid", you do have a few options:
If you have a dedicated Apache/PHP instance just for this project of yours, set the disable_functions option in php.ini and turn off all file and network related functions. This will affect the entire PHP installation and will break some surprising things, like phpmyadmin.
If you don't have a dedicated server, try 'runkit': http://php.net/manual/en/book.runkit.php to disable functions only within an already running script.
Perhaps more work? Setup a virtual machine (VirtualBox, VMware, etc) which is aggressively firewalled from within the Host OS, with a minimal allocation of memory and diskspace, and run the untrusted code there.
If you are paranoid... setup an approval process for all uploaded code.

Categories