Posts Tagged ‘Zend Framework’

Multiple Config Files with Zend_Application

February 28th, 2010

With the recent release of Manuscript, one of the things I added to the application was an installer. The installer is pretty basic and just asks for some database information that gets written to the config files.

This posed a problem. Zend_Config_Writer will only write to a file, not update it. I would need to read in all the sections of the application.ini file (production, testing, development) and take into account any sections added by users and dependencies, remove the old file and write the new one. That seemed very heavy handed and dangerous.

Zend_Config has a merge() function, so the idea came to me to use two config files. Keep the application.ini file for system values that are ‘global’ across installations, and then added a local.ini for things like DB settings. Zend_Config_Writer would just write local.ini settings to the global space and everything would be great. Merge the local settings into the application settings and your done!

A problem surfaced. Manuscript is built using Zend_Application. Zend_Application takes care of all the bootstrapping, reading the config files, and setting up all the dirty stuff for me. It also only takes the path of single config file. I have two config files. Crap.

Luckily Zend_Application doesn’t automatically bootstrap itself, but it does load the configuration immediately. What I ended up doing was this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
 
$localConfigFile = APPLICATION_PATH.'/configs/local.ini';
if(is_file($localConfigFile)) {
    $config = new Zend_Config($application->getOptions(), true);
    $local  = new Zend_Config_Ini($localConfigFile);
    $config->merge($local);
    $application->setOptions($config->toArray());
}
 
$application->bootstrap()
            ->run();

You initialize Zend_Application like normal and call the default application.ini. Zend_Application makes that config file available as an array, so I pull the loaded config back out and pass it into a new array-based Zend_Config ($config in the above). I create a second config ($local) with Zend_Config_Ini.

Using merge(), I merge the $local file into the $config file. This gets me a proper representation of what I wanted. I push this config back into Zend_Application and then call the bootstrap. The bootstrap is none the wiser that it actually is using two config files and my database gets bootstrapped properly!

It is not as clean as I want it to be but it gets the job done and users can override or add their own config information to local.ini and not worry about editing the supplied config file in the release.

Uploading Files using Zend Framework

January 7th, 2010

Uploading files in PHP is easy, if not tedious. A lot of the projects that I work on involve some type of upload of files and after a while it gets old. Doing all the checks to make sure the file is there, generating forms, etc … there must be an easier way, right?

Well, there is. The Zend Framework introduced a few classes to help facilitate uploading and working with files after they make it to the server. Taking advantage of Zend_Form_Element_File and the Zend_File_Transfer_Adapter_Http makes it dead simple to upload a file.

» Read more: Uploading Files using Zend Framework

Don’t Trust Your Users

November 3rd, 2009

My programming teacher was full of useful acronyms when it came to teaching us things. KISS (Keep it Simple Stupid), DRY (Don’t Repeat Yourself), IPO (Input-Process-Output), and probably one of the most useful, if understated:

GIGO = Garbage In, Garbage Out

Those four letters are probably some of the most ignored four (OK, three) letters in programming. Most programmers assume wrongly that their users are not out to get them and destroy precious data, but they are. Fortunately most users don’t know that they are trying to destroy the precious balance that most web apps have, and unfortunately most web apps don’t care. Programmers then have to worry about the rest of the users that are trying to abuse the system, and then the users who are maliciously attacking the system. By ignoring GIGO, you end up with a sad list like the OWASP Top 10.

OWASP Top 10 – We Shouldn’t Need It

Despite what that heading says, I’m not saying that the Top 10 is a bad thing. It’s just sad that most of the vulnerabilities can easily be done away with if programmers just take a little extra time and remember to treat everything that a user submits as garbage. Let’s take a look two that should have never made the list, let alone made it to the top two:

What do both of these problems have in common? Both are caused by applications blindly accepting user input. The problem is made even more sad by the fact that PHP, especially, has many tools available to help mitigate these two types of attacks.

Filtering Out Cross Site Scripting

Cross Site Scripting, or XSS, is actually a form of injection, but instead of being executed by the server it is executed by the user’s browser. The classic example, one that happens so frequently it makes an appearance in the satirical Forum Warz, is of the guestbook or forum that just displays whatever a user types in back to everyone. Since the Forum (in this case) doesn’t actually do any filtering on the user’s input when they make a post, they can enter things like this:

[cce_html]
U’ve been pwned!!!!!~~~!!11009“1~

<script type=”text/javascript”>alert(document.cookie);</script>
[/cce_html]

While the author of the forum may have never intended for users to type in HTML tags, in this case a user did. Now anytime someone visits that post, a pop-up will show the cookie data to the user. An actual attack would probably post that back to a URL and be completely silent. So, how do we get rid of this attack?

PHP’s Filtering Functions

Whitelist HTML Tags with strip_tags()

strip_tags() can either be used in two ways – remove all the HTML tags in a string or to only remove tags that are not in a white list. This is convenient if you want to allow a subset of HTML to be used in an input form.

[cce_php]
// Grab the user’s input from POST
$message = $_POST['message'];

// Just remove all the HTML tags
$message = strip_tags($message)

// Only allow basic text formatting such as Bold, Italics, Underline
$whitelist = ‘<b><i><u>’;
$message = strip_tags($message, $whitelist);
[/cce_php]

This will filter out that nasty <script> tag in either case. This makes it extremely nice if the app uses a WYSIWYG editor like TinyMCE or FCKEditor that uses HTML natively instead of something like bbcode.

Convert HTML with htmlentities()

htmlentities() converts HTML entities (special characters) into their viewable equivalents. For example, to display the ‘less than’ symbol (<) you should actually type in ‘&lt;’ to make sure that browsers display it properly. htmlentities() will take a string and convert anything that has an entity to it.

[cce_php]

// Message is = <b>This is cool!</b>
$message = $_POST[‘message’];

// Now we’ll get: &lt;b&gt;This is cool!&lt;/b&gt;
echo htmlentities($message);
[/cce_php]

This is useful when you want to take text as it is and return it so that it displays properly. It has the side effect of also destroying attacks that rely on HTML tags since they tags are converted into displayable entities instead of interpreted by the browser. I call this a side effect because I don’t really suggest using htmlentities() in this way. If you are not going to allow HTML at all, strip it with strip_tags().

Use PHP 5’s filter_input for a common interface

PHP 5.2.0 introduced a new funtion, filter_input(), which allows for a single function to do different types of filtering and validation.

[cce_php]
// These two should do the exact same thing, strip all HTML Tags
$message = filter_input(INPUT_POST, ‘message’, FILTER_SANITIZE_STRING);
$message = strip_slashes($_POST[‘message’]);
[/cce_php]

While nice, it needs to be expanded a bit to become extremely functional for anything other than basic use.

Zend_Filter Makes it Way To Easy

Zend_Filter, part of the Zend Framework, exposes a great deal of filtering and makes it easy to integrate with allowing user input. Zend_Filter will filter using:

  • Alphanumeric
  • Only Alpha (with or without whitespace)
  • Numeric
  • HTML Entities
  • Whitelist HTML Tags

[cce_php]
$alnum = new Zend_Filter_Alnum(true); // Filters out everything but letters, numbers, and spaces
$alpha = new Zend_Filter_Alpha(); // Filters out everything but letters, including spaces
$tags = new Zend_Filter_StripTags(); // Filters out just HTML Tags
$message = “Let’s <b>filter</b> this message out!!!111!”;
echo $alnum->filter($message); // Lets bfilterb this message out111
echo $alpha->filter($message); // Letsbfilterbthismessageout
echo $tags->filter($message); // Let’s filter this message out!!!111!
[/cce_php]

Zend_Filter also allows for Filter Chains that allow a programmer to add a bunch of filters and apply them all at once. This is useful if you want to strip out all the HTML, and then strip out any remaining special characters, unlike the first filter example where the text inside the tags is left.

The real jewel with Zend_Filter comes when used with Zend_Form. Zend_Form allows for forms to be built in PHP and then sent to the browser. When generating elements for the form, the programmer has the option to add filters and validations to elements that are fired off when the form is processed. A full tutorial is beyond the scope of this article, but the documentation shows how to use filters on the elements here.

Remember, Don’t Trust Your Users

I’ll tackle Injection attacks in another post, as there are different types of injection attacks. For now though, always remember to sanitize and filter ANY input that you accept from the user. While most users are not trying to be harmful, there are ones out there that are. It also means one less thing you have to worry about being a flaw or bug in an application.

PS: Hungarian Notation

One thing that may be useful that I picked up from Joel Spolsky is the concept of (proper) Hungarian Notation. Have a read through his post for the proper way to do Hungarian Notation and why it makes sense.

Major Upgrade to BiffCMS

February 7th, 2009

One of the nice things about switching BiffCMS to using the Zend Framework from the now extremely old and not-PHP5 BiffAPI that it used to run on is flexibility with power. Due to Zend Framework’s nature of allowing the programmer to do what they want instead of forcing them into a design paradigm, BiffCMS is now more modular.

What was overhauled?

The basic folder structure and some plumbing were overhauled in the last few days. The introduction of a ‘plugins’, a ’sections’, and a better theme system were all moved around and coded to allow for easier development. If you were using the Zend Framework version of BiffCMS all you will need to do is move some files around, but this is not a simple ‘overwrite files’ kind of upgrade.

Plugins

The heart of BiffCMS has always been Modules, which dictate what pages you can add to your site through BiffCMS. Since this has a much different term to Zend Framework developers these are now renamed Plugins and are much more easy to develop. Using the new ‘plugins’ folder, each plugin is now fully self contained inside its own folder. Need to install a new plugin? Drop it into the ‘plugins’ folder and go from there (still needs to be manually entered into the DB, but work on installation is coming along).  I’ve also added an Externallink plugin that allows pages that direct to outside URLs.

Sections

BiffCMS is built using Zend Framework’s MVC components and therefore has full support for Zend Framework modules (collections of Controllers and View Scripts). BiffCMS calls these Sections and they can be used when a simple page Plugin is not enough. Drop them into the ’sections’ folder and add them to the index.php page just like a regular Zend Framework module. Work is also progressing on allowing Sections to be enabled and disabled via the admin GUI.

Theming

The last thing a web developer wants is for his website to look like everyone elses. BiffCMS now has support for packaged themes, much like the BiffAPI version used to. Just create a folder containing at least a ‘layout.phtml’ and an ‘admin-layout.phtml’, drop it into the ‘www/themes/’ folder, and you can select it from the System Config portion of the Admin. These are just regular Zend Framework layout files so existing layouts can be easily ported.

Administration

Along with the above changes, BiffCMS now supports adding and editing users (deleting coming soon!), the beginnings of a System Config section to allow low level config changes like Themes, and a better Plugin management system.

If you want to check it out, head over to http://code.google.com/p/biffcms and check out a copy of the SVN. Within a few weeks there will be a formal release as some loose ends are tied up.

Tankersley Web Solutions running BiffCMS

January 18th, 2009

I’ve been meaning to do this for a while since BiffCMS has stablized to the point where I feel comfortable running it in production since switching it to Zend Framework from the old BiffAPI that it had been running. This is good since I just finished setting up and working on the website for Dragonlance: What If?, a new MUSH that will be going into beta this week.

Want to know how easy it is to get up and running with BiffCMS? I installed the app, ported the layout, and added a few pages in just about four hours total. Less than half of a day and I’ve got a site that I’m happy with and will have to do less to maintain than the straight Zend Framework-based site that was there before.

Want to try out BiffCMS? Head on over to the Google Code site and check out the latest working copy. I’ll be bundling a full release here within a week or so.