About the Author

Chris Shiflett

Chris Shiflett is an author and speaker who leads the web application security practice at OmniTI.


Security Corner: Session Fixation

Security is gaining more and more attention among PHP professionals. As PHP continues to be a key component of the Web's future, malicious attackers will begin to target weaknesses in PHP applications more frequently, and developers need to be ready.

I am very pleased to introduce Security Corner, a new monthly column that is focused completely on PHP security. Each month, I will discuss an important topic in great detail that can help you improve the security of your PHP applications and defend against various types of attacks. These topics will not be vague, general overviews, so if you are looking for an introduction to PHP application security, you will be better served by other sources of information such as the PHP manual's chapter on security.

This month's topic is session fixation, a method of obtaining a valid session identifier without the need for predicting or capturing one. The name for this type of attack originates from a publication by Acros Security entitled Session Fixation Vulnerability in Web-based Applications, although the method itself predates the publication. I will expand on the basic idea of session fixation and demonstrate some methods of prevention, all in a PHP-specific context.

Session Fixation

Session security is a vast and complex topic. One of the fundamental principles of Web application security is to never trust data from the client. However, in order to achieve statefulness, the client must identify itself by sending a unique identifier. This fundamental conflict creates significant complexities for developers wanting to build secure, stateful applications. In fact, the session mechanism in any Web application is likely to be that application's most vulnerable feature, and session security is one of the most complex topics of Web application security on any platform.

There are numerous types of session-based attacks. Many of these fit into a category called impersonation (session hijacking), where a malicious user attempts to access another user's session by posing as that user. At the very least, these types of attacks require that the malicious user obtain a valid session identifier, because this is the minimum amount of information that must be used for identification.

There are at least three ways that a valid session identifier can be obtained by an attacker:

  1. Prediction
  2. Capture
  3. Fixation

Prediction only involves guessing a valid session identifier. This guess can range from a wild guess to an educated one, depending upon the sophistication of the attack being used. With PHP's native session mechanism, valid session identifiers are extremely difficult to predict, so this is unlikely to be the weakest point in your implementation.

Capturing a valid session identifier is much more common, and there are numerous types of attacks that use this approach. When a cookie is used to store the session identifier, a browser vulnerability might be exploited in order to obtain the session identifier. When a URL variable is used, the session identifier is more exposed, and there are many more potential methods of capture. For this reason, cookies are generally considered to be more secure than URL variables for session identifier propagation, although user preferences must be honored, and browser vulnerabilities exist in all versions of the most popular browser, Internet Explorer (see peacefire.org/security/iecookies/ and Passport Hacking Revisited for more information).

Session fixation is a method that tricks a victim into using a session identifier chosen by the attacker. If successful, it represents the simplest method with which a valid session identifier can be obtained.

A Simple Attack

In the simplest case, a session fixation attack can use a link:

<a href="http://host/index.php?PHPSESSID=1234"> 
Click here
</a>

Or a protocol-level redirect:

<?php 
header
('Location: http://host/index.php?PHPSESSID=1234');
?>

Other methods include the Refresh header, whether passed as a legitimate HTTP header or by using a meta tag's http-equiv attribute. The point is to get the user to visit a remote URL that includes a session identifier of the attacker's choosing. This is the first step in a basic attack, and the full-circle attack is illustrated in Figure 1.


Figure 1: A typical session fixation attack

If successful, the attacker is able to bypass the necessity of capturing or predicting a valid session identifier, and it is subsequently possible to launch additional and more dangerous types of attacks.

Think you're not vulnerable? Consider the code in Listing 1. Save this code as session.php somewhere where you can test it. After you ensure that you have no existing cookies from the same host (clear all cookies if you're not certain), use a URL ending in session.php?PHPSESSID=1234 to visit the page. For example, http://host/session.php?PHPSESSID=1234. The script should output 0 on your screen upon your first visit. Reload the page a few times, and you should notice the number incrementing each time, indicating the number of previous visits.

Listing 1
<?php 
session_start
();

if (!isset(
$_SESSION['count']))
{
   
$_SESSION['count'] = 0;
}
else
{
   
$_SESSION['count']++;
}

echo
$_SESSION['count'];
?>

With a different browser, or even an entirely different computer, go through the exact same initial steps. Upon visiting the URL for the first time, you will notice that you do not see 0. Rather, it recalls your previous session. Thus, you have impersonated the previous user. Now, if you consider that this all began with a session identifier being passed in the URL, you should see the basic danger that session fixation presents. Unlike a typical scenario, PHP did not generate the session identifier.

There are a few shortcomings to this simplistic type of attack. The most important shortcoming is that the target application must use the session identifier passed to it, otherwise this attack will fail. If your session mechanism is nothing more than session_start(), your applications are vulnerable, as the previous demonstration illustrates. In order to prevent this specific vulnerability, you should always ensure that a new session identifier is used whenever you are starting a session for the first time. There are many ways this can be achieved, and one example is given in Listing 2 (this approach, too, has at least one weakness, so wait until you finish this article before deciding on the solution that best fits your needs).

Listing 2
<?php 
session_start
();

if (!isset(
$_SESSION['initiated']))
{
   
session_regenerate_id();
   
$_SESSION['initiated'] = true;
}
?>

If the code in Listing 2 is used to start all sessions, any existing session will always have a session variable named initiated that is already set. If this is not the case, the session is new. The call to session_regenerate_id() replaces the current session identifier with a new one, although it retains the old session information. So, if the attacker coerced a user into using an external link to your application that contains the session identifier, this approach will prevent the attacker from knowing the new session identifier, unless the session has already been initiated.

A Sophisticated Attack

A more sophisticated session fixation attack is one that first initiates a session on the target site, optionally keeps the session from timing out, and then executes the steps mentioned previously.

An alternative to the approach used in Listing 2 is to call session_regenerate_id() whenever a user successfully logs in, since this is the moment the session data becomes sensitive for most applications. For example, whenever you validate a user's username and password, you might set a session variable that indicates success:

$_SESSION['logged_in'] = true;

Just prior to setting such a session variable, a call to session_regenerate_id() can help to protect against a session fixation attack:

session_regenerate_id(); 
$_SESSION['logged_in'] = true;

In fact, a good approach is to always regenerate the session identifier whenever the user's privilege level changes at all, including situations where the user must re-authenticate due to a timeout. By doing this, you can be sure that a session fixation vulnerability is not the weakest aspect of your access control mechanism.

This approach is more secure than the previous example, because it adds another significant obstacle for an attacker to overcome, and it prevents sophisticated attacks where a valid session is first created and maintained. Unfortunately, it still may have at least one weakness, although your application design should already prevent it.

An Advanced Attack

In the most advanced type of session fixation attack, the attacker first obtains a valid account on the target application � and this is typically only appealing when the attacker can do so anonymously. On some PHP applications, the login page is a separate script, such as login.php, and this script may not check the user's state, because it seems safer to assume that the user has not been authenticated.

On the contrary, this approach can allow an attacker to create a session, log into the application with that session, optionally keep the session from timing out, and use the URL to the login page to launch the attack. If the login page accepts the new user's login but fails to regenerate the session identifier (because the privilege level has not changed), a vulnerability exists.

This scenario may seem unlikely, but a thorough examination of your code with this situation in mind is well worth your time. There are two easy ways to prevent this particular issue:

  1. Have the login page recognize the user's state.
  2. Always regenerate the session identifier on the receiving script, regardless of the user's state.

Until Next Time...

A good generic recommendation for preventing session fixation attacks is to regenerate the session identifier anytime the user provides authentication information of any kind. Be wary of passing along such a simplistic catch-all suggestion, however, because misinterpretations are likely when someone is unfamiliar with the type of attack being prevented. There is no substitute for a good understanding of session fixation, and it is possible that the best prevention for your applications is not even mentioned in this article.

Hopefully, you can now eliminate session fixation from your list of serious security risks with which to be concerned. If you develop a particularly creative method of prevention, I would love to hear it. Until next month, be safe.

About This Article

Security Corner: Session Fixation was last updated on 16 Feb 2004.

41 Comments

1. Dharmesh Acharya's GravatarDharmesh Acharya said:

Hi,

Can you suggest some ready made class or library for easy and secure session handling..

Dharmesh

Tue, 14 Sep 2004 at 09:41:24 GMT Link


2. Dennis's GravatarDennis said:

Hi,

Thank you for the valuable information!

Yes, I would like to see a sample secure session library/class myself. Through I have a lot of information to do it myself.

Tue, 14 Sep 2004 at 22:35:34 GMT Link


3. mariussk at epost dot no's Gravatarmariussk at epost dot no said:

this lines:

session_regenerate_id();

$_SESSION['logged_in'] = true;

Was the most useful on your article.

Wed, 02 Feb 2005 at 09:34:33 GMT Link


4. chris's Gravatarchris said:

niec tutorial, not sure how I'm going to use it though. I think I need a more indepth tutorial. If this happens please let me know

Tue, 08 Mar 2005 at 11:44:17 GMT Link


5. r^a's Gravatarr^a said:

using adodb mcrypted sessions ..basically regenerates the id on every 3 page loads and verifys browser/ip on everyload.... works perfect... a little overhead but worth it...

public function check()

{

$last_session_id = session_id();

if(!empty($_SESSION['page_view_count']) && $_SESSION['page_view_count'] % 3 == 0)

{

adodb_session_regenerate_id();

}

$new_session_id = session_id();

$last_access = time();

if (empty($_SESSION['hash']) || empty($_SESSION['last_access']))

{

$_SESSION['last_access'] = $last_access;

$_SESSION['hash'] = md5($_SERVER['HTTP_USER_AGENT'] . ':' . $_SERVER['REMOTE_ADDR'] . ':' . $last_access . ':' . $new_session_id);

$_SESSION['page_view_count'] = 1;

}

else

{

if($_SESSION['hash'] == md5($_SERVER['HTTP_USER_AGENT'] . ':' . $_SERVER['REMOTE_ADDR'] . ':' . $_SESSION['last_access'] . ':' . $last_session_id))

{

$_SESSION['last_access'] = $last_access;

$_SESSION['hash'] = md5($_SERVER['HTTP_USER_AGENT'] . ':' . $_SERVER['REMOTE_ADDR'] . ':' . $last_access . ':' . $new_session_id) ;

$_SESSION['page_view_count']++;

}

else

{

$this->destroy();

}

}

}

Sat, 12 Mar 2005 at 21:56:13 GMT Link


6. maxx gass's Gravatarmaxx gass said:

you could also use challenge codes which get changed on every page load, just like recent versions of PEAR::Auth

Sun, 15 May 2005 at 09:57:29 GMT Link


7. ezee's Gravatarezee said:

Great article. I am an amateur to PHP and I was just wondering ... if the attack is launched via a url such as http://host/index.php?PHPSESSID=1234

... then, why can't we just check the $_SERVER["REQUEST_URI"] to see if it contains "PHPSESSID=".

Is there some other way that the attacker can launch the attack?

Thanks.

Fri, 01 Jul 2005 at 19:31:32 GMT Link


8. Greenwood's GravatarGreenwood said:

Thanks a lot for your articles, Chris

Sun, 11 Sep 2005 at 12:10:43 GMT Link


9. Gasper's GravatarGasper said:

Hi,

Thank you for the valuable information!

Yes, I would like to see a sample secure session library/class myself. Through I have a lot of information to do it myself.

Mon, 12 Sep 2005 at 19:40:37 GMT Link


10. Richard's GravatarRichard said:

I didn't know about session_regenerate_id() so thanks for pointing this out and explaining it so clearly.

Sat, 08 Oct 2005 at 12:39:11 GMT Link


11. Buraque's GravatarBuraque said:

I didn't even know that there is a security problem like this.

Thank you for this very useful info.

I have patched my pages already.

I am not an expert PHP coder. I am using a single index.php file, and include the content page according to the <i>index.php?page=somepage</I> directive in URL.

So every click, every move in my site loads index.php file.

My solution was, in the index.php I put:

session_start();

$save_session = $_SESSION;

session_regererate_id();

$_SESSION = $save_session;

I have tested it. It creates a new session_id everytime, and I am keeping the session variables intact.

Anyone have any comment on the way I am using? Any potential problems?

Thank you.

Sun, 23 Oct 2005 at 16:03:53 GMT Link


12. Web Development Company India's GravatarWeb Development Company India said:

Hope In php5 problem are less

Thu, 27 Oct 2005 at 08:59:38 GMT Link


13. hallwhere's Gravatarhallwhere said:

Does this apply to server only? If not, what can we do to increase security in our browser?

Tue, 01 Nov 2005 at 03:20:44 GMT Link


14. James's GravatarJames said:

Greate site. Thank you :)

Tue, 01 Nov 2005 at 14:33:12 GMT Link


15. Richard's GravatarRichard said:

Buraque, you do not need the $save_session; this is done automatically for you.

Thu, 10 Nov 2005 at 22:36:33 GMT Link


16. Zinho's GravatarZinho said:

Greetings,

I've finished my research on session fixation attacks and way to prevent it. It covers the best techniques to follow to be safe from such attacks.

You can find it here:

http://www.hackerscenter.com/archiv...ew.asp?id=21242

Hope it helps

Thu, 22 Dec 2005 at 19:07:33 GMT Link


17. Abdul Majid's GravatarAbdul Majid said:

I've read the article and i feel blown away - there must be quite a large market for providing php security consultancy

Mon, 26 Dec 2005 at 19:34:51 GMT Link


18. Phil's GravatarPhil said:

When I process the login script I regenerate the session ID and store it in a variable in the session

$_SESSION['sess'] and then set $_SESSION['logged_in'] = true

At the beginning of each page that is restricted I check session_id() against $_SESSION['sess'] and I check $_SESSION['logged_in']

Is that enough, or am I just kidding myself?

Wed, 25 Jan 2006 at 21:28:50 GMT Link


19. sole's Gravatarsole said:

The URL to the PHP security page doesn't seem to be working, but this one does:

http://us2.php.net/manual/en/security.php

Keep up the good work! :D

Thu, 25 May 2006 at 14:32:56 GMT Link


20. James Nelson's GravatarJames Nelson said:

Great article. I was the victim of an attack a few weeks ago and I suspect it was session hijacking. Thanks for the info - I have patched my apps!

Sat, 30 Sep 2006 at 18:18:24 GMT Link


21. Mat's GravatarMat said:

Just to follow up on r^a's comment. I found an annoying problem today when using HTTP_USER_AGENT to avoid session fixation attacks.

When using the context menu's "Download Linked File" in Safari, it reports the user agent as CFNetwork/129.16

Fri, 20 Oct 2006 at 14:19:09 GMT Link


22. Dan's GravatarDan said:

There is a good secure_session class located at

http://www.phpclasses.org/browse/package/2794.html

I've used this class and can vouch for it. It optionally regenerates the session id, checks the remote IP address, and check's the user's browser.

Only trouble I had was with AOL users. Since their requests come from all the place (different proxy servers) I had to shut off the IP address checking...

Fri, 10 Nov 2006 at 08:29:13 GMT Link


23. system's Gravatarsystem said:

You could always set "session.use_only_cookies" to 1 in php.ini, much easier :p

Thu, 01 Feb 2007 at 18:50:22 GMT Link


24. Chris Shiflett's GravatarChris Shiflett said:

Yes, much easier, but it doesn't offer sufficient protection.

Fri, 02 Feb 2007 at 22:19:39 GMT Link


25. shg's Gravatarshg said:

How about:

if (isset($_COOKIE[session_name()]))

setcookie(session_name(), '', 0, '/');

session_destroy();

insted of:

session_regenerate_id();

$_SESSION['logged_in'] = false;

when users loggs out? Is it more secure? I'm using this in my script, after destroying the session, comes the 'Location' header, which redirects user to the main page, and new session is started then (each page includes the login.php script, so session is started always when session data, i.e. cookie, is not present).

Great articles, thanks!

Sun, 04 Feb 2007 at 17:04:22 GMT Link


26. Joe's GravatarJoe said:

This article helped me a lot I was the loser of an attack a few weeks ago and I suspect it was session hijacking. Thanks for the info - I have patched my apps!

Thu, 15 Feb 2007 at 15:49:37 GMT Link


27. newbie's Gravatarnewbie said:

How about an in depth tutorial, as a PHP learner, all I seem to find are snippets of code that are not complete enough to understand or use. You are obviously very talented at this, us new to PHP would dearly relish a PROPER tutorial, not like some of the tutorials that are out there.

Sun, 25 Feb 2007 at 17:44:45 GMT Link


28. Brendan Falkowski's GravatarBrendan Falkowski said:

This is an excellent article. Session fixation attacks are starting to be discussed more in PHP security circles. There is a whitepaper from the PHP website that explains the topic as well. It may be of additional help to some.

http://www.acros.si/papers/session_fixation.pdf

Sat, 24 Mar 2007 at 20:04:24 GMT Link


29. Alex's GravatarAlex said:

For all those who asked for ready made secure session classes, i recommend learn how sessions work, and then writing your own secure session class, so that you are not blind to the operation of your website

Thu, 19 Apr 2007 at 22:35:20 GMT Link


30. Elan's GravatarElan said:

Hello. Thankyou for this very usefull information.

I was just reading what other users had said and it is all good storing the session in a cookie, but what if the user doesnt have cookies enabled?

thanks.

Wed, 11 Jul 2007 at 23:31:40 GMT Link


31. Hossein's GravatarHossein said:

Hello,

Dear chris,

These sentences are in your book,From Chapter 4,

Please explain more about them:

1-

To make propagation a bit easier to manage, you might consider keeping the entire query string in a variable. You can append this variable to all of your links, which makes it easy to refactor your code later, even if you don't implement this technique initially.

2-Keep in mind that a browser includes a Cookie header in all requests that satisfy the requirements set forth in a previous Set-Cookie header. Quite commonly, the session identifier is being exposed unnecessarily in requests for embedded resources, such as images. For example, to request a web page with 10 images, the session identifier is being sent by the browser in 11 different requests, but it is needed for only 1 of those. To avoid this unnecessary exposure, you might consider serving all embedded resources from a server with a different domain name.

May you give me example about this " different domain name"?

3-The Refresh header can also be usedprovided as an actual HTTP header or in the http-equiv attribute of a meta tag. The attacker's goal is to get the user to visit a URL that includes a session identifier of the attacker's choosing. This is the first step in a basic attack; the complete attack is illustrated in Figure 4-3.

Thanks in advance,

Tue, 17 Jul 2007 at 08:00:39 GMT Link


32. Alexander Waldmann's GravatarAlexander Waldmann said:

@Hossein: May you give me example about this " different domain name"?

He means: Your scripts are accessed on server domain1.com and the images referenced in the html code are coming from domain2.com - because the domain is differently, any cookies for domain1.com containing the session id will not be transmitted while requesting the images.

In general it is quite useful to use 2 different servers serving static resources (files that don't change, e.g. images, downloadable files, etc.) because this can also increase performance. Imagine one lightweight webserver (apache with almost no modules compiled in) for serving static resources and a heavyweight server with all necessary modules for script execution.

kind regards

Alex

Tue, 28 Aug 2007 at 13:00:14 GMT Link


33. Shade's GravatarShade said:

I put in a check for "PHPSESSID" in the GET string (I could modify it to check for POST as well), no matter where on the site they're trying to go, and print out a special error message to raise their awareness of the attack. I might be going a bit too far in checking the entire GET string (not just variables), but I figure that paranoia is a better foundation to work from than gullibility; FIRST users become accustomed to the simple question of "Is there a PHPSESSID string in this link I was given?", THEN (when/if they ever feel up to it) they can move on to parsing the string, only looking for substrings following a ? or & symbol, etcetera.

Thu, 10 Apr 2008 at 05:17:16 GMT Link


34. Different Dennis's GravatarDifferent Dennis said:

To remove another vulnerability, session_regenerate_id(); should be replaced with session_regenerate_id(true);

On this link:

http://ilia.ws/archives/47-session_regenerate_id-Improvement.html

Ilia Alshanetsky highlights that in the session_regenerate_id() function, when it renames the session id it does not remove the old session, leaving it active and potentially usable by a would be hacker.

I (Different Dennis) checked this and it's true. You can check for your self by storing your session data in a directory that you can access (using the session_save_path command) to see what session files are in it.

1. Using the following, each time a new id is created, the old session file is left behind, with the data still in the file. So each time the following is called, one more old session file is added to the session directory.

session_start();

session_regenerate_id();

2. The following solves this. Each time a new id is created, the old session file is deleted.

session_start();

session_regenerate_id(true);

Regards

Different Dennis

Sun, 13 Apr 2008 at 11:46:57 GMT Link


35. Shade's GravatarShade said:

@Dennis:

This is only a vulnerability if you don't have any checks in your code for which privileges a given session/ID has. Keeping the old session alive may be desirable so that, if an attacker got in ahead of the user, you can display a message upon a 2nd successful login attempt to the effect of "This system has already logged you in once, if this is your first time logging in you may click here to terminate both connections.", and if someone is attempting to log in after the first user successfully has, you can display a message to them reporting how many attempts and suggesting ways they can check their local security.

You can keep track of the new session ID with a variable in the old session, and vice versa.

Tue, 15 Apr 2008 at 17:54:07 GMT Link


36. yacahuma's Gravataryacahuma said:

I was not able to replicate your text. I copied the listing 1. open firefox and visit de link. Started from 0. click a couple of times

Then open explorer and visit the link and I started from 0 again

Could my php configuration cause this?

Sat, 03 May 2008 at 01:13:48 GMT Link


37. Sam Wilson's GravatarSam Wilson said:

Anyone want to comment on the explanations and code about session fixation in the PHP wikibook? It could certainly do with some help I think...

http://en.wikibooks.org/wiki/Programming:PHP/sessions

Thanks!

Wed, 07 May 2008 at 06:26:36 GMT Link


38. James Magee's GravatarJames Magee said:

I have a method that I implemented into my Browser Based Rpg Login Script, along with the examples above I also generate a random string(8-12 characters-md5'd) upon logging in, then a login time is generated and stores a session variable(named after the login time) whose value = the random string. The string and login time are stored in a mysql database md5 encrypted as well. Upon entering pages which require you to be authenticated it will check the PHPSESSID and the login time session variable, if either or are incorrect..well relogin pursues... Let me know what you think and if there are vulnerabilities in this as I haven't opened it to the public yet.

Mon, 02 Jun 2008 at 04:19:05 GMT Link


39. Arran Schlosberg's GravatarArran Schlosberg said:

After some quick experimenting I noticed that although the session data is moved to a new ID the old one is still available. If I am correct about this then it raises 2 important points:

1) Pass the parameter true to session_regenerate_id(true) as this will remove the old session.

2) Regenerate the ID prior to performing the changes to the session data as this will still render the original ID (assuming you failed to perform (1)) useless.

Sorry if I repeated anything Chris wrote here. I never read the article but have used his book extensively so thought I'd share something that I don't remember reading elsewhere.

Following the "defense in depth" strategy both (1) and (2) should be performed. A quick and dirty example:

<?php
 
// ... authenticate and set $authenticatedUser appropriately ...
if($authenticatedUser!==false){
  session_regenerate_id(true); //remove the old session
  $_SESSION['user'] = $authenticatedUser; //done after the regeneration
}
 
?>

Wed, 10 Sep 2008 at 00:05:49 GMT Link


40. Jaymar's GravatarJaymar said:

Hi, nice article..

I have one question though, if you turn off global variables on your php.ini, will the type of attack mentioned above (where the the session id was implied by the attcker by adding PHPSESSID to the URL) still be possible?

If you turn off global variables, $_SESSION variables will be different from $_GET variables, so I'm assuming that this will no longer be a problem..

Can anyone comment on this?

Mon, 26 Jan 2009 at 06:16:17 GMT Link


41. sean's Gravatarsean said:

Great article!!! I was wondering about the following code, which would seem open to a fixation attack, but is not...

This is the beginning of the private page...

<?php

session_start();

if (!isset($_SESSION['user']))

{

header("Location: http://[address of login page]?requestedpage=[token for this page]");

exit();

}

...

If an attacker caused a known user to request the above page with ?PHPSESSID=1234, the session_start would then register 1234 as the current session

This is from the login page...

<?php

if($_POST['[a posted form var]'])

{

// check submitted credentials against known users

$status = authenticate(...);

// if user/pass combination is correct

if ($status == 1)

{

// initiate a session

session_start();

// register some session variables

$_SESSION['XXXXXX] = filter($_POST['XX']);

// redirect to protected page

header("Location: ...[requested page]);

exit();

}

}

When the user logged in above, the session_start would use the session cookie from the first session_start above and have a validated session with an SID known to the attacker.

However, the top snippet does not cause an SID to be recorded in a cookie, but the bottom one does. Hence, the attack is prevented, but why?

Thanks, cheers!

- Sean

Mon, 16 Feb 2009 at 18:54:05 GMT Link


Post A Comment

Personal Details and Comment

Style Guide

Line breaks are converted to paragraphs. Also use:

  • <a href="" title="">text</a>1
  • <em>text</em>
  • <blockquote><p>text</p></blockquote>
  • <code>2  <?php  if ($foo) {      $foo = TRUE;  }  ?></code>
  1. Note: <code> can be used inline (e.g. in paragraphs) or in a block as shown. Include whitespace and newlines in blocks.

Please enter Chris (my first name) below. This is a primitive spam prevention technique, and I apologize for the inconvenience.

Preview and Submit

New Comments

Ronald wrote:

A little hard for a rookie like me, but useful. I also thought you'd like to know there is a grea...

Posted in A rev="canonical" HTTP Header
Alex wrote:

Aren't you forgetting that the session will expire if _write() is never called? That excludes ...

Posted in
Andy Mabbett wrote:

@Chris Shiflett, #4, belatedly: Google only accepts rel=canonical within the same domain. My s...

Posted in A rev="canonical" HTTP Header
Kenneth Udut wrote:

I've implemented this rev="canonical" idea on http://free.naplesplus.us in the hopes that it catc...

Posted in Save the Internet with rev="canonical"
Mark wrote:

After reading your article and all the comments, what I got out of this was that sessions are not...

Posted in

Browse Comments