Zend PHP5 certification Exam study review 4: Web Programming, Web Features

Finally, we get into the WEB PROGRAMMING. This is what php was made for! This is a VERY VERY important aspect in the exam. Make sure you have understood how COOKIE, SESSION, HTTP headers, SUPER GLOBALS, etc works in PHP. Also, the exam requires you know some of the PHP configuration directive (in the php.ini file) regarding PHP’s Web Features, such as “magic qoutes gpc”, “safe mode” etc. And in this area, many security issues also related. You should know some implements in PHP to avoid common security problems, such as what FORM TOKENS for; what’s Browser Fingerprinting for, and so on.
Forms
. GET vs POST
. Form Tokens
. Default Values
. Re-populating data

.superglobal array

$_GET[]
$_POST[]

When You Don’t Know How Data Is Sent
$_REQUEST[]
filled in using data from different sources in an order specified by a setting in your php.ini(usually, EGPCS, meaning Environment, Get, Post, Cookie and Built-in variableS. Note that $_REQUEST only contains cookie, GET and POST information).

The problem with using this approach is that, technically, you don’t know where the data comes from. This is a potentially major security issue that you should be fully aware of. This problemis discussed in more detail in the Security chapter.

You can create arrays by using array notation…
http://example.org/index.php?list=user&order[by]=column&order[dir]=asc
There is nothing that stops you from creating URLs that already contain query data—there is no special trick to it, other than the data must be encoded using a particular mechanism that, in PHP, is provided by the:

urlencode()

The PHP interpreter will automatically decode all incoming data for us, so there is no need to execute urldecode() on anything extracted from $_GET.

Managing File Uploads

A file can be uploaded through a “multi-part” HTTP POST transaction. From the perspective of building your file upload form, this simply means that you need to declare it in a slightly different way.

<form enctype=”multipart/form-data” action=”index.php” method=”post”>
<input type=”hidden” name=”MAX_FILE_SIZE” value=”50000″ />
<input name=”filedata” type=”file” />
<input type=”submit” value=”Send file” />
</form>

As you can see, the MAX_FILE_SIZE value is used to define the maximum file size allowed (in this case, 50,000 bytes); note, however, that this restriction is almost entirely meaningless, since it sits on the client side—since any moderately crafty attacker will be able to set this parameter to an arbitrary value, you can’t count on it preventing any attempt to overwhelm your system by sending files that are so large as to deplete its resources.

You can limit the amount of data uploaded by a POST operation by modifying a number of configuration directives, such as post_max_size, max_input_time and upload_max_filesize.

Once a file is uploaded to the server, PHP stores it in a temporary location and makes it available to the script that was called by the POST transaction. It is up to the script to move the file to a safe location if it so chooses—the temporary copy is automatically destroyed when the script ends.

$_FILES[]

$_FILES[‘name’]
$_FILES[‘type’]
$_FILES[‘size’]
$_FILES[‘tmp_name’]
$_FILES[‘error’] The error code associated with this file. A value of UPLOAD_ERR_OK indicates a successful transfer, while any other error indicates that something went wrong.

is_uploaded_file()

move_uploaded_file() a call to this function also checks whether the source file is a valid upload file, so there is no need to call is_uploaded_file() first.

One of the most common mistakes that developers make when dealing with uploaded files is using the name element of the file data array as the destination when moving it from its temporary location. Because this piece of information is passed by the client, doing so opens up a potentially catastrophic security problem in your code. You should, instead, either generate your own file names, or make sure that you filter the input data properly before using it!

HTTP Headers
Simple strings in the form key: value, terminated by a newline character. The headers are separated by the content by an extra newline.

header()
Set cookies manually, using the RFC for the appropriate headers.

the header() must be called before any other output, including any whitespace characters outside of PHP tags, as well as all HTML data and PHP output. If you fail to abide by this rule, two things will happen: your header will have no effect, and PHP may output an error.

Note that you may be able to output a header even after you have output some data if output buffering is on. Doing so, however, puts your code at the mercy of what is essentially a transparent feature that can be turned on and off at any time and is, therefore, a bad coding practice.

Header(); redirects
.Do they work?

Redirection
header(“Location: http://phparch.com“);
vs
header(“Location: http://phparch.com“);
exit();

To stop browsers from emitting “Do you wish to re-post this form” messages when clicking back after submitting a form, you can use a header redirection to forward the user to the results page after processing the form.

Other arbitrary headers
.Header injection attacks
.Caching

No Caching:
header(“Cache-Control: no-cache, must-revalidate”);
header(“Expires: Thu, 31 May 1984 04:35:00 GMT”);
Set expires in the future:
$date = gmdate(“D, j M Y H:i:s”, time() + 2592000); // 30 Days from now
header(“Expires: ” . $data . ” UTC”);
header(“Cache-Control: Public”);
header(“Pragma: Public”);

.Content-Type
.Meta Information

Compression
HTTP supports the transparent compression and decompression of data in transit during a transaction using the gzip algorithm. Compression will make a considerable impact on bandwidth usage—as much as a 90% decrease in file size. However, because it is performed on the fly, it uses up many more resources than a typical request.

The level of compression is configurable, with 1 being the least compression (thus requiring the least amount of CPU usage) and 9 being the most compression (and highest CPU usage). The default is 6.

Turning on compression for any given page is easy, and because the browser’s Accept headers are taken into account, the page is automatically compressed for only those users whose browsers can handle the decompression process:

ob_start(“ob_gzhandler”);

Placing this line of code at the top of a page will invoke PHP’s output buffering mechanism, and cause it to transparently compress the script’s output.

You can also enable compression on a site-wide basis by changing a few configuration directives in your php.ini file.

zlib.output_compression = on
zlib.output_compression_level = 9

Notice how this approach lets you set the compression level. Since these settings can be turned on and off without changing your code, this is best way of implementing compression within your application.

Cookies

.Can be deleted, manipulated, copied.
.Behavior is inconsistent.

Cookies allow your applications to store a small amount of textual data (typically, 4-6kB) on a Web client.
There are a number of possible uses for cookies, although their most common one is maintaining session state.

Cookies are typically set by the server using a response header, and subsequently made available by the client as a request header.

cookies should always be treated as “tainted” until proven otherwise.

setcookie()
Wraps the Header function, sets default values when nothing is passed.

Should you wish to make a cookie persist between browser sessions, you will need to provide an expiration date. Expiration dates are provided to setcookie() in the UNIX timestamp format(the number of seconds that have passed since January 1, 1970).Remember that a user or their browser settings can remove a cookie at any time—therefore, it is unwise to rely on expiration dates too much.

setcookie(“hide_menu”, “1”, time() + 86400);

three more arguments:
path, domain, secure


$_COOKIE[]

Cookie values must be scalar.

The amount of storage available is severely limited—therefore, you should keep the amount of data you store in cookies to a minimum, and use sessions instead.
Remember that setting cookies is a two-stage process: first, you send the cookie to the client, which will then send it back to you at the next request. Therefore, the $_COOKIE array will not be populated with new information until the next request comes along.

reset the cookie
There is no way to “delete” a cookie—primarily because you really have no control over how cookies are stored and managed on the client side. You can, however, call setcookie with an empty string.


Sessions

Sessions are maintained by passing a unique session identifier between requests—typically in a cookie, although it can also be passed in forms and GET query arguments.
.Sessions, The safer way to state.
.Use a cookie that contains a Session ID.
.That Session ID corresponds with a local(ish) data store that contains the user’s information.
.The Session ID is the only data that is transmitted to a client, and is also the only thing that identifies them.

PHP handles sessions transparently through a combination of cookies and URL rewriting, when session.use_trans_sid is turned on in php.ini (it is off by default in PHP5) by generating a unique session ID and using it track a local data store (by default, a file in the system’s temporary directory) where session data is saved at the end of every request.

Sessions are started in one of two ways. You can either set PHP to start a new session automatically whenever a request is received by changing the session.auto_start configuration setting in your php.ini file. Or explicitly call session_start() at the beginning of each script.

When sessions are started automatically, the session is started before your scripts are executed; this denies you the opportunity to load your classes before your session data is retrieved, and makes storing objects in the session impossible.In addition, session_start() must be called before any output is sent to the browser, because it will try to set a cookie by sending a response header.

In the interest of security, it is a good idea to follow your call to session_start() with a call to session_regenerate_id() whenever you change a user’s privileges to prevent “session fixation” attacks.

$_SESSION[]

Session Hijacking and Session Fixation

Conclusion:
Data comes in from GET or POST, frequently from forms, don’t trust it.
Cookies are a client side data store.
Sessions use cookies to offer a localish datastore.
Header allows us to send meta information to the client.

4 Comments - Leave a comment
  1. Heena says:

    how does one create a cookie which will exist only until the browser session is terminated?
    1> you cannot create cookie that expire when the browser session is terminated
    2> setting the expiration time for a cookie to a time in the distance future
    3> do not provide a cookie expiration time
    4> enable cookie security
    5> set a cookie withour a domain

  2. David Adam says:

    Hi, the answer is 3> do not provide a cookie expiration time.

  3. Amit Verma says:

    The default value of “output_compression_level” is -1, NOT 6.
    Please recheck :)

  4. […] Web Programming & Web Features […]

Leave a Reply

Your email address will not be published. Required fields are marked *

*