Authoring/Development - Using PHP
PHP is a powerful, server-side scripting language that can be used to extend the functionality of your pages in many ways. It is available for use with any account level at pair Networks, and is activated by naming the files that use it with the extension .php. Currently, we have PHP 5.3.18 installed on our new Web servers.
The syntax of PHP is very similar to popular programming languages such as C and Perl. If you have any previous programming experience, it is likely that you'll be able to pick up PHP in short order. No one tutorial could ever cover the hundreds of built-in PHP functions, so we highly recommend following and reading over all the related links given at the bottom of this article.
How To Include PHP Code
PHP is embedded within a page by enclosing commands within the start tag <?php and the end tag ?>
<?php
echo "This text written by PHP!\n";
?>
Normal HTML tags and text cannot be included within blocks of PHP code. You can output HTML code from within a PHP block to the browser by using the echo command as shown above, or by ending the PHP block, resuming normal HTML, and later starting a new PHP block.
You can include as many separated blocks of PHP code in your file as you need, and any variables you set will be available to the block it was set in, and any block below that.
PHP Variables
Variables are assigned in a typical manner. Normal variables are preceded with a $, and assigned to with =. Any variable can be used in an array by including a key in square brackets after the variable.For a regular array, a number is used as the key. For an associative array, a quotes enclosed string (or another variable) is used. The function "array" can also be used to create arrays of either type. The code below illustrates these features (lines beginning with "//" are comments):
<?php
// Normal variable assignment
$person = "Bob";// Assigning to a regular array
$fruit[0] = "apple";
$fruit[1] = "grape";
$fruit[] = "orange"; // see explanation below// Assigning to an associative array
$mother['kitten'] = "cat";
$mother['puppy'] = "dog";// Using the array function for a regular array
$fruit = array('apple','grape','orange');// Using the array function for an associative array
$mother = array('kitten' => 'cat', 'puppy' => 'dog');// The following line prints "Bob's cat ate an orange."
echo "$person's $mother[kitten] ate an $fruit[2].";
?>
In the sixth line above, "orange" is assigned to the regular array $fruit with no index given. This tells PHP to assign it the next available number, and thus it becomes assigned to $fruit[2].
Access To Form Variables
One of the most powerful features of PHP is its easy access to form variables. For instance, consider the following short form:
<form method=post action="form_handler.php">
<input type=text name="formvar">
<input type=submit>
On submitting the form, the value of the variable "formvar" will be available to the form_handler.php script simply as $formvar with no parsing required on your part. This is true for both POST and GET form calls.
The form_handler.php will also have easy access to all environmental variables in the same manner (the REMOTE_HOST variable can be accessed as $REMOTE_HOST, for instance). This is true of all calls to PHP scripts, not just ones that were originated from a form.
PHP Arithmetic Operators
Arithmetic operators in PHP are virtually identical to those in Perl, as illustrated by the example code below:
<?php
// Addition
$ADD = $VAR + 3;// Subtraction
$SUB = 18 - 6;// Multiplication
$MULT = $VAR1 * $VAR2;// Division
$DIV = 15 / $VAR;// Modulus (Division to get remainder)
$MOD = $VAR % 2;
?>
PHP Control Structures
PHP provides most basic control structures seen in other languages, among them the looping constructs for and while, and the standard if/else construct. Examples are given below:
<php
// for Loop Example
for ($I = 0; $I <= 10; $I++) {
print "Current Iteration: $I\n";
}// while Loop Example
$I = 0;
while ($I <= 10) {
print "Current Iteration: $I\n";
$I++;
}// if/then/else Example
if ($I > 20) {
echo "$I is greater than 20.\n";
} elseif ($I > 10) {
// notice that PHP uses "elseif" instead of Perl's "elsif"
echo "$I is greater than 10.\n";
} else {
echo "$I is less than 10.\n";
}
?>
PHP File Access
PHP also allows you full ability to read and write to files in your account. Files are opened via the fopen command, which is given in the form:
$FILE = fopen("filename","mode");
where $FILE is the variable you'll use to refer to the open file, filename is the name of the file to be opened, and, mode determines level of access to the file using one of the following values:
- r (read only)
- r+ (read and write)
- w (write only)
- w+ (read and write, truncate file to 0 bytes)
- a (write only, start at end of file -- append)
- a+ (read and write, starting at file end)
Once the file is opened, there are two commands to read in data. fgetc retrieves a single character, while fgets retrieves a number of bytes you specify. They are used in the following manner:
$ONECHAR = fgetc($FILE);
$TENBYTES = fgets($FILE,10);
If you need to write to the file, the function used is fputs:
fputs($FILE,"This text is written to the file");
After you are done interfacing with the file, you must close your file descriptor with the fclose command:
Please note that our PHP configuration disallows the loading of URLs via include(), require(), file(), and similar routines. For example:fclose($FILE);
<?php include("http://www.example.com/script.php"); ?>If you wish to take advantage of this feature, you can turn it on for your account by adding the following configuration line to your .htaccess file:
php_flag allow_url_fopen onIf you are using php5.cgi in conjunction with php-cgiwrap, you should copy /usr/local/etc/php5/php.ini to the same directory as your copy of php5.cgi, and remove the line that references allow_url_fopen from the file entirely.
Please note that this configuration only affects attempts to load URLs via these functions. It has no affect on loading files from the server itself.
The sample code below uses the file functions and a while loop to copy the contents of data.txt to newdata.txt. (Not particularly useful in "real life," but good for demonstrative purposes.)
<?php
$FILE = fopen("/usr/home/username/data.txt","r"); // open data.txt for reading
$NEWFILE = fopen("/usr/home/username/newdata.txt","w"); // open newdata.txt for writing// continuously read in from data.txt
while ($BUFFER = fgets($FILE,4096)) {
fputs($NEWFILE,$BUFFER); // write line to newdata.txt
}fclose($FILE); // close data.txt
fclose($NEWFILE); // close newdata.txt
?>
Protecting Your E-Mail Forms from Exploits Be warned that we come in contact with many successful exploits against customer PHP scripts that send e-mails. These exploits are intended to send out junk e-mail across the Internet.
In many cases, we are able to detect such abuses and prevent the e-mail from being sent out. In other cases, though, it is indistinguishable from normal activity.
When we locate a vulnerable script that is actively being attacked, we are disabling it and notifying the customer.
How The Exploit Typically Works
In almost all cases, the attack works by placing a newline character (represented by \n in the following example) in the field that asks for the user's e-mail address. For instance, they might put:
joe@example.com\nCC: victim1@example.com,victim2@example.comIf a script uses that e-mail address as the From header of the resultant e-mail, and does not carefully check the contents before using it, the script is likely to create these headers:
To: youraddr@example.comAnd the e-mail is sent to all of the addresses.
From: joe@example.com
CC: victim1@example.com,victim2@example.com
This exploit can be done against any form data that is placed in the headers of an e-mail, be it From, Subject, or another field.
How To Protect Your Site
Our strong recommendation is to use the formmail.pl and cgiemail scripts we provide in our system cgi-bin wherever possible. cgiemail in particular is very flexible and can suit most e-mail gateway needs.
Those scripts have been extensively tested and hardened against this and other types of exploits.
If you need to use a custom PHP script as an e-mail gateway, please ensure you are filtering all data received from the form, and remove any unexpected characters. For instance, this sample code snippet would check for all the non-printable codes in the standard ASCII set, including null bytes and newlines, and exit immediately if any are found.
if (preg_match("/[\\000-\\037]/",$EMAIL)) { die(); }
In this example, $EMAIL is used to represent a variable that contains form data. Such filtering should be done on all variables containing form data that are used in the headers of the e-mail.
Related Links:




