CSS Tips and Tricks Collection

We see different CSS tips and tricks articles almost in every popular website. However, different articles have their own CSS tips and tricks. This makes me wondering that it will be great to have one single CSS tips and tricks collection. A collection that gather all great tips and tricks that has been found since the beginning popular demand of CSS. Well, this might as well be a selfish article that i would like to have for my own collection. Hence, in this article you might just find all of the great CSS tips and tricks that might satisfy your CSS work demand! (This article does not include techniques)

Tips

Below gathered all the tips that might help you change the way you write CSS.

Avoid Hacks

ie-kit-end-user-internet
Try avoiding using hack to solve your problem for IE 6 and below. Sometimes it might not be the problem of compatibility that caused your CSS not working on IE. It might just be the mistake made by you. Furthermore, you can't guarantee that these hack will work forever in the future. It might just come back hunting you in the future. We never know when new browser will have the capability to read those tag right?

Organize CSS definition

organize-file-folders
It is a good practice to always organize your CSS definition. Depending on how you organize it might just help you in term of usability and maintainability in the future. You can try organizing your CSS definition by block,

/*Header*/
/*Content*/
/*Footer*/
/*Siderbar*/
/*Menu*/

Maintaining this way allows you to easily find the tag whenever you needed a change. On the other hand, you can also arrange it according to type such as

h1{}
h1.listitem{}
h1#special{}

h2{}
h2 div{}
h2.someitem{}
h2#gooditem{}

This way of organization may be good as comment is unnecessary. However, many redundancy might occur. We can also write down references on top of the CSS header to keep us reminded on the choices we made for our CSS definition.

/***References***
* Author: Clay Lua
* Created: 01/01/2009
* Last Modified: 18/07/2009
* Theme Name: Wack My Ass Theme
* Description: this theme will surprise visitors with a butt kicking color theme
* Image used: whatever.jpg, hello.jpg, home.jpg, contact.jpg
* Color used: #000, #FFF, #365, #CCC
* Font used:  Arial, Helvetica, sans-serif;
***************/

Some of us might like it and some of us are just too lazy to deal with it. However, keeping such record might help you track down who was the last culprit that masses up your CSS definition!

Group Similar Selector

box-group-different
This is something that majority of us will know what to do. The concept of grouping similar selector is quite simple. Instead of having so many line of similar definition. We group them up instead. For example,

.example1{#color:#000}
.example2{#color:#000}
#example3{#color:#000}
h2{#color:000}

Writing something like this might just help you increase the time needed to load your stylesheet. Do yourself a favor and group them instead.

.example1,.example2,#example3,h2{#color:#000}

This really can help you cut down some fat bytes if you are practicing the initial declaration. But what if grouping the definition breaks down your organization? We will just have to place these grouping on a special organization block or provide special comment on them. What if a specific element have somewhat more definition than the others but share some similarity? Grouping still should be done and for those outcast, we will just declare them separately such as this,

.example1,.example2,#example3,h2{#color:#000}
.h2{font-size:2em}

We are using h2 as an example here that have the following declaration originally.

.h2{font-size:2em;#color:#000;}

Since, everyone share the same color, we can optimize them by grouping the color together to avoid many lines needed for the same color to appear at different location. Hence, reduce the number of line in the CSS file.

Avoid Unnecessary Selector

Like developer program to be efficient by writing less code to achieve something big. Similarly, we want to achieve the same with CSS by writing less definition and at the same time achieve the overall design so that the view can be loaded quickly. There are many times we see CSS definition such as these:

div#unique{color:#000}
h2.group{color:#392}

Since id and classes really meant to refer to a specific tag. We can safely remove the type of the tag and achieve the same result with these:

#unique{color:#000}
.group{color:#392}

Avoiding unnecessary selector such as the type of the tag can help us reduce some bytes on the stylesheet. Furthermore, we really don't need them! Some of us would like to do this:

#main {
width: 530px;
padding: 10px;
float: left;
}
#main #nav{
background: #fff;
width:100%
}
#main #left-col {
background: #ef;
margin: 8px 0;
}

for organization purposes having multiple id #main selector to remind us that they are related is a great thing but do we need them when we already organize our definition using comment block? Think about it.

Use meaningful name

spell-your-name
Other than organizing our CSS definition in our file. Another important thing is to use meaningful name for each class and id. Having these name makes people understand what does the definition stand for and makes life easier in the future if you ever want to maintain it. Like many developers are taught to use meaningful name for their function/method in a class, same thing apply to CSS. Having a name such as this

#kelly{}
#dolly{}
#melly{}
#merlly{}
#molly{}

compare to this

#header{}
#footer{}
#content{}
#siderbar{}
#menu{}

do make a difference. (who will have guess header is actually kelly?!)

Alphabetical Properties

Another important thing in declaring your CSS within a definition is the arrangement of each property. Having an alphabetical order properties can really help you scan out the property much easier than arranging it disorderly. Everyone who uses a dictionary will know how useful it is to arrange it this way compare to a dictionary which messes their arrangement up. Luckily, there are a href='http://hungred.com/useful-information/really-useful-web-based-tools-speed-web-development/'>web based tools that can help us do this quickly. Here is an example of an alphabetical order properties:

body {
background:#fdfdfd;
color:#333; font-size:1em;
line-height:1.4;
margin:0;
padding:0; }

Avoid !important

important-nature-pot
Some of us love !important when we want to overwrite certain xyz person CSS definition and have no clue or simply lazy to find them out. For conveniences, this is pretty good. However, using too many !important might just destroy your site usability. There are two types of !important. One refers to author and the other refers to the user. Once, author uses !important, it will always prioritize higher than the user one. Hence, any changes made by the user will be invalid. This means any changes such as font size and color will be deem invalid. Hence, usability, fail.

CSS order priority

In order to better improve usability. The only thing we need to understand is CSS order priority. Rather than simply using !important to overwrite others CSS definition. We can avoid them by taking advantage on how CSS prioritize each element. You can easily understand them in CSS priority order tips and tricks

Use CSS ShortHands

If you want to speed up your website. This is something you must learn. It is a good practice to always use CSS shorthands as it helps to optimize your stylesheet. Instead of declaring something like this,

#image{
background-image: url(images/someimage.jpg);
background-repeat: no-repeat;
background-color: transparent;

we can reduce the above definition by using shorthand such as

#image{background: transparent url(images/someimage.jpg) no-repeat 100% 100%};

Not only property have shorthand in CSS, we can also apply shorthand on colors too!

color: #000000
color: #FFFFFF
color: #554422

Each of the above can be written as

color: #000
color: #FFF
color: #542

It is actually identical. CSS shorthands is powerful and quite easy to learn.

Avoid Unnecessary length type

length-short

Often we see people declaring a type for '0' which is totally unnecessary as it is understood that '0' is universal in term of any given type. Hence,

0em
0%
0px
0in
0cm
etc.

is the same as

0

Why not remove the unnecessary type for value 0? This can definitely reduce some byte if in every 0 in your style has included a type.

Case Sensitive

There is a differences between an uppercase compare to a lowercase in CSS. Therefore, we need to understand that every definition name must be identical to the tag written in order for CSS to work properly. Hence, i always use lowercase to make things simplify.

Remove Redundancy

redundancy-gay-stupid

We often forget and tend to write extra or duplicate declaration in order to try an error hoping for it to work and forget to remove those extra property written in our definition. This naturally increase the number of duplication and redundancy in our CSS file. The browser will have to do extra job and the client will have to download the extra bytes. Try removing these duplication with any web based tools or minimize it a long the way.

Avoid Many Absolute Positioning

Some of us love to use absolute positioning as it is easy and get the job done quickly. However, absolute position also means that the element is positioned absolutely at that location even if you minimize the browser? This means that if you absolute position a particular sidebar to the right with a floating element on the left, it will not 'minimize' upon browser minimization. On the other hand, it will move along with the browser during minimization and might caused your layout to break (because it is absolutely required to be positioned at THAT position). Hence, try avoiding using absolute position unless necessary.

Avoid Unnecessary Classes

We often can see something amusing such as this

<ul id='unorder'>
	<li class='list'></li>
	<li class='list'></li>
	<li class='list'></li>
	<li class='list'></li>
	<li class='list'></li>
</ul>

But it can simplify and remove the class instead to something cleaner and smaller.

<ul id='unorder'>
	<li></li>
	<li></li>
	<li></li>
	<li></li>
	<li></li>
</ul>

And have a CSS definition such as this

#unorder li{color:#000}

And this is what it means to have unnecessary class. We just do it sometimes Unconsciously.

Use EM for layout

Using EM to layout which is also known as elastic layout design is great for your website. It has both fixed and fluid layout design advantages. This means that your layout will not break whenever user resize their font size. We won't want our design to break whenever user perform such stunt don't we? Smashing magazine writes an excellent article about it!

Validate your code

validate

It is always a good practice to validate your code throughout the development life cycle of your theme. Validating your CSS code will ensure that everything is correct and assure that mistake is not being made by you but the browser instead.

Rationale your code

Similar to validating your CSS code. It is also important to rationale whether the decision made is necessary. Determine whether each definition can be improve by grouping, shorthands, remove redundancy or it can be done without adding that extra wrapper.

Planning and thinking might just what you need before working on any CSS code in order to produce a better and more understandable code.

Reduce div block

We often see many new designers using many div block on their design making it totally difficult to manage. Even tag such as H1,H2,H3,H4,ol,ul,li,strong,em,span are being replaced with div block. There are other tag for a reason! Utilize them! This makes your overall design more readable and understandable. Maintaining it won't be difficult and people will be more appreciative (without scolding you behind your back) towardsthe way you design your website.

Import CSS Style

97717028.jpg

Another good practice is to a master CSS file to import other CSS files. This way we will only required to write one sentence on the header of the HTML file and leave the rest to the master file. On the other hand, importing your CSS files also help remove compatibility for IE4 (this means we import statement is not support on IE4). Hence, you should write your CSS in this way to avoid IE4 to import your CSS file.

@import "file.css";

centricle has a very nice chart for this.

Use CSS Conditional For IE

Instead of using CSS hack on every browser, we can specific these hacks to a particular IE browser instead by using CSS conditional comments.

<p><!--[if IE]>
According to the conditional comment this is Internet Explorer<br />
<![endif]-->
<!--[if IE 5]>
According to the conditional comment this is Internet Explorer 5<br />
<![endif]-->
<!--[if IE 5.0]>
According to the conditional comment this is Internet Explorer 5.0<br />
<![endif]-->
<!--[if IE 5.5]>
According to the conditional comment this is Internet Explorer 5.5<br />
<![endif]-->
<!--[if IE 6]>
According to the conditional comment this is Internet Explorer 6<br />
<![endif]-->
<!--[if IE 7]>
According to the conditional comment this is Internet Explorer 7<br />
<![endif]-->
<!--[if gte IE 5]>
According to the conditional comment this is Internet Explorer 5 and up<br />
<![endif]-->
<!--[if lt IE 6]>
According to the conditional comment this is Internet Explorer lower than 6<br />
<![endif]-->
<!--[if lte IE 5.5]>
According to the conditional comment this is Internet Explorer lower or equal to 5.5<br />
<![endif]-->
<!--[if gt IE 6]>
According to the conditional comment this is Internet Explorer greater than 6<br />
<![endif]-->
</p>

Take note that the syntax above gt means greater than whereas lte means less than or equal. Conditional comments is supported only in IE 5 and above. This way, your hack will not affect other browser during execution!

Cater To Different Views

lookout-see-view-look

We can provide different views to different devices by stating different media. We can have different CSS file for different media.

<link rel="stylesheet" media="screen,projection,tv" href="main.css" type="text/css">
<link rel="stylesheet" media="print" href="print.css" type="text/css">
<link rel="stylesheet" media="handheld" href="smallscreen.css" type="text/css">

The other way is to use the keyword @media to specific the style of the media.

@media screen, projection, tv {
  #foo { position: absolute; }
}
@media print {
  #navi { display: none; }
}
@media handheld {
  #foo { position: static; }
}

While the last way, we can use the @import to import the stylesheet for a particular media

@import url(bigscreen.css) screen, projection, tv;
@import url(print.css) print;
@import url(smallscreen.css) handheld;

However, this is not supported on IE version 7 and above.

Avoid Quote in URL

We can safely avoid any quote required in the url bracket. It is understood that within the bracket it should be a path. Hence, regardless whether there is a quote it will still work. Therefore, we can save some bytes in every situation where it required a url definition such as the one shown below,

@import url(example.css);
background: transparent url(css/image.jpg) no-repeat 100% 100%;

Optimize CSS File

optimize-web-contents

After we have completed our CSS styling. The final step is to optimize with file using any web based tools available online. Optimizing CSS file will greatly help reduce those extra bytes by reducing other criteria that we might omitted such as empty spacing, white space or extra closing tag at the end of each definition.

Tricks

Below gathered all the tricks necessary in almost every CSS but difficult to remember for some of us.

Absolute Position Within Container

The trick to absolute position anything within a container is letting the container position relatively!

#container{
position:relative;
width: 200px;
height: 200px;
border: #000 solid 1px;
}
#inside_element{
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
border: #000 dotted 1px;
}

#inside_element will position at the far left side of #container although it is position at coordinate (0,0). This is pretty simple. Just try it 🙂

Force Page Break

We will need to force a page break if we are dealing with printing media of our website. Hence, these can be pretty useful if you are catering such media view for your visitors.

h1{
	page-break-before:always;
}

h2{
	page-break-after:avoid;
}

h2{
	page-break-inside:always;
}

These methods are stated in W3school print properties and W3Org

Text transform

Transformers-Jazz-Pontiac-

We can perform text transformation on CSS alone. No JavaScript or PHP is required to style our text!

h1 {
	text-transform:uppercase;
}

h2 {
	text-transform:capitalize;
}

p {
	text-transform:lowercase;
}

PNG Fix in IE

We can fix png problem by using the following code

#myimage{
	background:none;
	float:left;
	width:150px;
	filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='test.png', sizingMethod='scale');
}

Although there are other solution such as using JavaScript. I will prefer a more shorter code approach.

Set Consistence Base Font Size

It is good to use em to size font instead of using px. This can really improve usability as the font will resize when focus. However, calculating EM is a pain in the ass. 1EM is equal to 16px. 1024px is equal to how much EM again? Argh, this is troublesome. We can convert it nicely by converting 1EM to 10px by doing the following.

body { font-size: 62.5% }

This way we can safely assume 1em is 10px and resizing the font won't hard.

p{
font-size: 0.8em; //8px
}

Pretty neat stuff.

Prevent Float From Over-float

elephant

If you haven't encounter such problem where your float element is floating all over the place and unstoppable! There are actually solution for you to treat these floating element as single block to prevent it to overlapped every element it sees. The solution is to use overflow:auto or hidden on top of the wrapper.

#container{
overflow: auto;
}
#container_floating_element{
float:left;
width: 100px;
height: 100px;
}

You can read more on the above solution and other solutions at Various Ways To Fix Container Height To Float Element In CSS

Sequence Of Anchor Pseudo-classes

In CSS, the sequences of the anchor pseudo classes is really important for it to work properly.

a:link {color:#FF0000}      /* unvisited link */<br />
a:visited {color:#00FF00}  /* visited link */<br />
a:hover {color:#FF00FF}  /* mouse over link */<br />
a:active {color:#0000FF}  /* selected link */<br />

You can read more on the tips of anchor pseudo classes at CSS order priority tips and tricks

Remove vertical scrollbar in IE

We can remove that ugly scrollbar in IE textarea by doing the following CSS definition:

textarea{
overflow: auto
}

Just that simple!

Use CSS global reset value

reset

This is every beginner CSS designer mistake. They often did not reset the CSS style before using it. It is important to reset the CSS style as different browser might have different default value. On the other hand, resetting the global value also help to ignore the need to define '0' value for any property. (this means margin: 0 is not needed if we have already reset it globally). Thus, reduce further more byte on the css file. There are many reset value for CSS. However, i will prefer the YUI one. We can either call it this way on our HTML (we don't host that extra file),

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.0r4/build/reset/reset-min.css">

Or you can embed the reset on your own CSS file

body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {
	margin:0;
	padding:0;
}
table {
	border-collapse:collapse;
	border-spacing:0;
}
fieldset,img {
	border:0;
}
address,caption,cite,code,dfn,em,strong,th,var {
	font-style:normal;
	font-weight:normal;
}
ol,ul {
	list-style:none;
}
caption,th {
	text-align:left;
}
h1,h2,h3,h4,h5,h6 {
	font-size:100%;
	font-weight:normal;
}
q:before,q:after {
	content:'';
}
abbr,acronym { border:0;
}

I will prefer letting YUI take care of the file since it doesn't hook up my bandwidth for that particular CSS request and it is much faster compare to share hosting.

Cross Browser Align Center

We can easily align center horizontally using margin and display property.

#container{
display:block;
width: 200px;
height: 50px;
margin: 0 auto;
}

On the other hand, achieving vertical alignment with horizontal one might be more complicated than usual.

body{
padding: 0;	//required to remove that distance line
margin: 0; //required to remove that distance line
}
#distance {
	width:1px;
	height:50%;
	background-color:#fc6;
	margin-bottom:-13.75em; /* half of container's height */
	float:left;
}

#container {
	margin:0 auto;	/* horizontal align */
	position:relative; /* position on top of distance */
	text-align:left;
	height:27.5em;
	width:45em;
	clear:left;
	background-color:#ff9;
	border:1px solid #c93;
	border-top-color:#fff;
	border-left-color:#fff;
}

Basically we will need two tag instead of just one container block.

<div id="distance"></div>
<div id="container">
hello
</div>

The above will give you a center alignment on the center that work even for IE5.5.

Cross Browser Align Center With Absolute

There are many ways to position at the center of the screen when your element is position absolute.

#container{
width: 100px;
height: 100px;
margin-left: -50px;
margin-top: -50px;
left: 50%;
top: 50%;
position: absolute;

You can visit Tutorial: How to align center on the screen when using position absolute with CSS for explanation and other ways of align center when position absolute.

Cross browser Min Width/Height

This is pretty useful for anyone who wish to design your website with a minimum width or height

#container{
width: 100px;
width: auto !important;
min-width: 100px;

height: 100px;
height: auto !important;
min-height: 100px;
}

Cross browser Opacity

The introduce of IE8 has change cross browser opacity a little.

selector {
	opacity: .75; /* Standard: FF gt 1.5, Opera, Safari */
	filter: alpha(opacity=75); /* IE lt 8 */
	-ms-filter: "alpha(opacity=75)"; /* IE 8 */
	-khtml-opacity: .75; /* Safari 1.x */
	-moz-opacity: .75; /* FF lt 1.5, Netscape */
}

thank-you-watching--crap

PHP Secure Login Tips And Tricks

Every website on the internet faces a similar threat, hackers. Every single website can be a target of a hacker if security measures aren't implemented properly especially when it comes to login pages where our most sensitive data are being held. Hence, there is a need to better understand how well your login page has been implemented to be considered as really secure. In this article, you will get a list of PHP secure login tips and tricks that will definitely help you decide on your secure rating of your login page.

Length Of your username and password

Both your username and password should be at least 6-8 characters long. A longer combination of username or password will make brute force attack or any other password cracking algorithm longer to crack. This can really help your network administrator to detect an attack before the attack penetrates through your login page.

Encrypt your password

We all know that encryption is necessary in term of any password. But i would still like to stress such importance. We are very dependent on encryption algorithms such as MD5 or SHA-1. However, these two algorithms are no longer that secure as compared to the older days. On Wednesday, February 16, 2005 SHA-1 has been broken by three china researchers. Although it is more towards collision attack rather than pre-image one we can assure one thing is that SHA-1 can be broken. You can read more about it on Bruce Schneier article. On the other hand, you can find MANY MD5 cracker online nowadays through Google. eg. md5crack.com. But similarly they are all collision attacks.  Wiki explains MD5 vulnerability in a way you will be discouraged from using it. It is time to encrypt your users password using SHA-2 such as sha256, sha384, sha512 or better. If you are using PHP 5.12 or above, there is a new function, hash that supports SHA-2.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  hash(’sha1′,$phrase);
$sha256= hash(’sha256′,$phrase);
$sha384= hash(’sha384′,$phrase);
$sha512= hash(’sha512′,$phrase);

For people who are using PHP 5.12 and below, you can try to use mhash which is an open source class for PHP.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  base64_encode(bin2hex(mhash(MHASH_SHA1,$phrase)));
$sha256= base64_encode(bin2hex(mhash(MHASH_SHA256,$phrase)));
$sha384= base64_encode(bin2hex(mhash(MHASH_SHA384,$phrase)));
$sha512= base64_encode(bin2hex(mhash(MHASH_SHA512,$phrase)));

SHA-2 should be used to secure your future application. Although MD5 and SHA-1 can still be used for authentication purposes with a very secure password combination. eg. (eQ@xC#Eif2dsa!e2cX2?"}23{D@.

NOTE**: NEVER DOUBLE HASH!

Double hashing is *worse* security than a regular hash. What you’re actually doing is taking some input $passwd, converting it to a string of exactly 32 characters containing only the characters [0-9][A-F], and then hashing *that*. You have just *greatly* increased the odds of a hash collision (ie. the odds that I can guess a phrase that will hash to the same value as your password).

sha1(md5($pass)) makes even less sense, since you’re feeding in 128-bits of information to generate a 256-bit hash, so 50% of the resulting data is redundant. You have not increased security at all.

Credit goes to Ghogilee

****updated on 8 Oct 09

On the note of Ghogilee, i found a few errors which i would like to point out. Double hashing here is referring to two different hash function.  It does reduce the search space but doesn't *greatly* increased the odds of a hash collision.  On the other hand, SHA-1 should be a 160-bit hash not 256-bit and not only does this doesn't increased the security but also weaken the hash function as the hacker will only required to crack the weaker hash function in this case md5.

You may want to visit Better Hashing Password in PHP for more information. If you wish to understand the risk and stuff you can do with hash function, please visit Enhance Security Hash Function For Web Development. Here i document the most detail hash function i could for your information.

Enhance Hash With Salt

Once you have decide your secure password encryption algorithm, the last thing you might want is to have different user having the same encryption algorithm hash code. This can bring another problem of more than one account being compromised at the same time when there are multiple same hash and short password can easily be cracked with ease when your database and tables have been known. We can generate a salt in order to overcome this problem so that the string is longer and more random (providing that the salt + password are random enough).

define('SALT_LENGTH', 15);
function HashMe($phrase, &$salt = null)
{
$key = '!@#$%^&*()_+=-{}][;";/?<>.,';
    if ($salt == '')
    {
        $salt = substr(hash('sha512',uniqid(rand(), true).$key.microtime()), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return hash('sha512',$salt . $key .  $phrase).$salt;
}

The above function contains two parameters. The first will take in a phrase and generate a SHA-2 salt if the second parameter is placed with an empty variable. However, if both parameters contain values, it will be used when you wish to compare between two hashes. We can use the above method this way,

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$hashed_password = HashMe($password, $salt);
$sqlquery = 'INSERT INTO  `usertable` ("username", "password", "salt") VALUES  ("'.$username.'", "'.<d>$hashed_password .'", "'.$salt.'") WHERE 1';
..

The above will insert the information into the table when user is being created. We will check the user with the following salt.

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$sqlquery = 'SELECT `salt`, `password` FROM  `usertable` WHERE `username` = "'.$username.'" limit 1';
..
#we get the data here and placed into variable $row
$salt = $row['salt'];
$hashed_password = HashMe($password, $salt);
if($hashed_password  == $row['password']){
#verified
}
else{
#ACCESS DENIAL
}
..

The objective of salt is to lengthen the password in the table and also create a totally random hash code for each password. Hence, even if your table is being compromised, it will really take a lot of time for them to crack those hashed password. (We are assuming login page already implemented protection against multiple false log in)

Do not use easy guess username for administrators

It is always wise to use a slightly more challenging username for any administrators on your system. Username like 'admin', 'root' or 'super' will surely be the one on the hacker list to determine any administrator username. Be smart! Use something more challenging such as 'iamtheking' as a username instead (if your login system is case insensitive).

Log user login attempt

It is actually wise to log every important event in a system. Definitely, login page is one of them. We can determine whether any attempt of attack on our system is being carry out with a proper logging system. The log file or table can be very useful to track back what had gone wrong during a specific time frame when an attack occurs to determine whether an attack was launched to determine whether the login page was compromised.

Handle Error

It is important to prevent any error from being displayed to malicious users. These information is very useful for them to determine how to break into your system. Hence, they will try any type of value in order to break your PHP functions. Therefore, an ampersat symbol (@) should be placed in front of any function to prevent an error from occuring. On the other hand, you can use the function mention on Solutions to SQL Injection Attack which uses die to generate a better SQL error message that can be both professional and at the same time log your errors. The function is shown below,

function sql_failure_handler($query, $error) {
	$msg = htmlspecialchars('Failed Query: {$query}<br>SQL Error: {$error}');
	error_log($msg, 3, '/home/site/logs/sql_error_log');
	if (defined(‘debug’)) {
		return $msg;
	}
	return 'An error occurs, please try again later.';
}

#query=test;DELETE FOM breakplease;
$query = 'SELECT * FROM user WHERE name ='. base64_decode($_GET['query']);
mysql_query('$query) or die(sql_failure_handler($query, mysql_error()));

Always filter user input

Remember on the articles Solutions to SQL Injection Attack and Solutions to Cross-Site Scripting (XSS) Attack which mention that filtering user input is very important as hackers will use any way to break your login system. The rule is to never TRUST your user input until every last verification gets through. You can use the following function in PHP for your filter assistance,

htmlentities()
strip_tags ()
utf8_decode ()
htmlspecialchars()
ctype_digit()
ctype_alnum()
stripslashes()
str_replace()

Be Innovative Not Informative

We must be innovative on the message we present to our users whenever an error or login fail occurs. Message such as 'invalid password' or 'invalid username' is bad practices that gives information to malicious user what they went wrong. Instead, provides something like 'Login Fail. Please try again' will be a much more appropriate approach.

USE LIMIT or WHERE 1

In SQL query, for any login attempt, always place a LIMIT 1 at the end of your SQL statement. If there is a chance where a successful SQL injection is performed, only one account is being compromised instead of all. On the other hand, using WHERE 1 can help prevent any additional SQL query from placing at the front of your where clause.

Check HTTP Referrer

The basic of every security check is to ensure that the HTTP referrer came from the form on your site. If the HTTP referrer is suspicious, reject the request immediately. Although, HTTP Referrer can be easily spoofed with JavaScript it is always good to have any form of protection on a login page. However, some firewalls or proxies strip this information out which will caused many of your users to be unable to login successfully. Hence, you might want to consider whether to implement such checking for your login system.

Nonce authentication

Another better way of authenticating than checking the HTTP Referrer is to use acryptographic nonce. A nonce is a number used once, and it is used for intention verification purposes. Think of it as a password for THAT particular form and only can be used once. It really depends on how you implement your Nonce between the client and server.

Use maxlength

It is definitely a great idea to only allow a maximum length of characters user can placed on an input box. This is like a restriction placing in front of malicious user to provoke their creativity in order to penetrate your system. However, you might not like this idea too as it minimize the number of combination for hackers to crack your login page. Personally i will place such restriction as my login page will never allow more than certain fail login.

$_POST ONLY

When dealing with any form data. The only answer is using $_POST. NO $_REQUEST or $_GET should be use as you are just making life easier for hacker and weaken your security. Although $_POST can still be used by hacker but it makes the job troublesome.

Sub String Not Trim

In a login page, it is best to secure ourselves. Hence, if a user made an error on their username or password, the system should not correct for them. If a user enters a username with leading or trailing space we are not going to trim it nicely for them before we check. On the other hand, we will sub string it out so that we are checking the maximum length that is being enforce on the text box.

MYSQL Accounts

It is important for any secure website to be cautious on the access given to MYSQL user account on the specific action. For login purposes, the only thing that the user allows to do is to retrieve data from MYSQL table. Hence, other actions such as delete, update, alter etc. should not be given to the login page. If a successful SQL Injection was launched on the site. Imagine the user updating your user account password to the one given. Our security measure will just kick us back to one. Hence, always be cautious on the access given to MYSQL user account.

Utilize IP

Always ensure that IP address is used together with session key after a user has logged into your portal. This can prevent Session attacks and at the same time ensure that the same person is viewing the content of your secure page. You can also use IP to ban certain users from trying to guess your login username or password upon certain tries. However, using IP may mean certain restrictions for certain companies or proxy users from accessing your website. Nonetheless, this can be solved by detecting their connection. You can use this script to detect whether they are behind proxy server

if (
      $_SERVER['HTTP_X_FORWARDED_FOR']
   || $_SERVER['HTTP_X_FORWARDED']
   || $_SERVER['HTTP_FORWARDED_FOR']
   || $_SERVER['HTTP_VIA']
   || in_array($_SERVER['REMOTE_PORT'], array(8080,80,6588,8000,3128,553,554))
   || @fsockopen($_SERVER['REMOTE_ADDR'], 80, $errno, $errstr, 30))
{
    exit('Proxy detected');
}

The above code should allows you to detect even anonymous proxy server.

*****Update 7 Oct 2009

I forgot to mention here that the above script will only be necessary if an IP address cannot be detected (Thanks Julius).

Utilize Cookies

I forgot to mention this important thing to you guys. There is also a need to tie cookie together with session and/or ip to prevent session hijack or cross-site request forgery (CSRF). The hacker might be able to hijack your session through different ways but cookies will still remind on your user client browser.

Cookies can also used for auto logout module by setting the expiry date of the cookie after 15 minutes and if the cookie doesn't exist, the user has been idle for 15 minutes. On the other hand, we can refresh this cookie every user activity. This is one of the many ways to implement auto logout functionality but this is not secure as the cookie can be stolen by hacker and prolong the duration of the cookie expiration time.

Lastly, we talk about locking user upon certain attempts but IP was difficult to be used. This can be solve by utilize cookie to set the number of tries performed by the user/browser. Using cookie is definitely insecure way of keeping track of user attempts but it also creates additional barriers for hackers to overcome. This should be used together with account lock functionality to prevent such weakness in your defense (this means cookie count and account attempts count should not be link together).

Auto Logged Out Mechanism

I forgot this one but one of the readers did not. Implementing an auto logged out mechanism onto your login system can really help prevent CSRF attacks. Since we can't control whether our user leave their account logged in while browsing or surfing the net, we can definitely cover their butt but having this mechanism up to prevent any CSRF or Session attacks. Since both attacks require the user to be logged in.

*****Update End

Lock upon certain fail attempt

This is something that most secure web pages should looked upon. A very good way of locking a user will be as follow,

  1. n times fail attempt locked m minutes
  2. n fail attempt due to 1. locked further m+30 minutes
  3. n fail attempt due to 2. locked for the whole day

An example will be as follows:

  • 3 times fail attempt locked 10 minutes
  • 3 fail attempt due to 3 times fail attempt locked 10 minutes subsequence locked 10+30 minutes
  • 3 fail attempt due to the above will result in whole day lock

You can lock a user based on IP or accounts. It will be better to lock them based on accounts IF proxy IP is unable to detect due to the fact that it is an anonymous proxy. IP should be used otherwise. This will prevent the user from guessing the correct username. On the other hand, if a username was guessed correct the same process can be applied and disabled the account by sending an email to the original author to reactive it. But the same message should be used. (not informative information!) If you are worry of blocking an entire proxy server or company employees, you can just go by account since breaking an account will required certain tries anyway.

SSL Encryption

No matter what you do on the above, without a secure line from the client to your server everything will be meaningless when it comes to packet sniffer which is also known as man in the middle attack. Especially for attacks such as Session Hijack. Password can be send directly into a hacker computer without the need to use brute force. The above mentioned methods definitely can stop newbies but not those that know their stuff. Without such encryption, getting your password won't be that difficult. Here's a video showing how easily it can be done without SSL encryption.

Summary

Any kind of system can still be compromised but the time and effort to compromised such system is another thing to be considered. The above mention methods are ways to make life difficult for hackers so that they will give up on penetrating your system. Hence, any little bit of security measure we can implement on our system is considered as a line of defense. There is never a bad thing by being paranoid in securing your web system. A website is like a man on an open field ready to be shoot at anytime! Do your website a favor. Wear a helmet. (not condom)

Better Hashing Password in PHP

Every developer should know that storing any type of password in plain text is the worst possible decision anyone can make in a secure environment. Between security and confidentiality which one will you choose? Nowadays hacking are perform through social engineering or an inside job, by an employee or trusted person. How exactly confident are you towards securing your stuff and confidentiality of your user? Most of us will know that the Reddit suffer from such problem when all their username and password were compromised as their password wasn't hashed and stored as plain text. And twitter was attacked through social engineering recently. We won't want this to happen to us right? Therefore, in this article you will get to know some ways to better hash your password in PHP and some ways to improve your security.

What is Hashing?

Hashing is a term used in encryption to perform a deterministic procedure that takes an arbitrary block of data and returns a fixed-size bit string. Any accidental or intentional attempt to change the data will change the hash value. Moreover, different message will have different hash value. There should not be an exact hash value with different message. And it is infeasible to find a message that has a given hash. Hence, many information security application uses hashing to protect or authenticate the confidentiality of the content of the application such as digital signatures, message authentication codes (MACs), and other forms of authentication.

Authenticate User

We use cryptographic hash function to hash our password. And all of us should not be aware of what is being placed as password in the table. So how do we authenticate these users password since hash value is a one way encryption? This can easily be achieve through comparing the hash value against the one user has keyed in and the one stored in our database!

Rainbow table Attack

A rainbow table attack is a form of lookup table that aim to decode the hash value in order to make hashing feasible to find a message that has a given hash. Rainbow table attack is usually used against cryptographic hash function after they have retrieved a hash value. However, we can better protect ourselves by adding SALT onto our plain text to make it more infeasible for rainbow table to retrieve pain text with a given hash value.

SHA-1 and MD5

We all know that hashing is necessary in term of any password. But i would still like to stress such importance. We are very dependency on encryption algorithm such as MD5 or SHA-1. However, these two algorithm is no longer that secure as compared to the older days. On Wednesday, February 16, 2005 SHA-1 has been broken by three china research. Although its more towards collision attack rather than pre-image one we can assure one thing is that SHA-1 can be broken and its weaker than we thought. You can read more about it on Bruce Schneier article. On the other hand, you can find MANY MD5 cracker online nowadays through Google. eg. md5crack.com. But similarly they are all collision attacks or rainbow table. Wiki explains MD5 vulnerability in a way you will discourage using it. Its time to encrypt your users password using SHA-2 such as sha256, sha384, sha512 or better.

Hashing your password

If you are using PHP 5.12 or above, there is a new function, hash that supports SHA-2.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  hash(’sha1′,$phrase);
$sha256= hash(’sha256′,$phrase);
$sha384= hash(’sha384′,$phrase);
$sha512= hash(’sha512′,$phrase);

For people who are using PHP 5.12 and below, you can try to use mhash which is an open source class for PHP.

$phrase = 'This is my password';
$sha1a =  base64_encode(sha1($phrase));
$sha1b =  base64_encode(bin2hex(mhash(MHASH_SHA1,$phrase)));
$sha256= base64_encode(bin2hex(mhash(MHASH_SHA256,$phrase)));
$sha384= base64_encode(bin2hex(mhash(MHASH_SHA384,$phrase)));
$sha512= base64_encode(bin2hex(mhash(MHASH_SHA512,$phrase)));

SHA-2 should be used to secure your future application. However MD5 and SHA-1 can still be use for authentication purpose with a very secure password combination. eg. (eQ@xC#Eif2dsa!e2cX2?"}23{D@.

NOTE**: NEVER DOUBLE HASH!

Double hashing is *worse* security than a regular hash. What you’re actually doing is taking some input $passwd, converting it to a string of exactly 32 characters containing only the characters [0-9][A-F], and then hashing *that*. You have just *greatly* increased the odds of a hash collision (ie. the odds that I can guess a phrase that will hash to the same value as your password).

sha1(md5($pass)) makes even less sense, since you’re feeding in 128-bits of information to generate a 256-bit hash, so 50% of the resulting data is redundant. You have not increased security at all.

Credit goes to Ghogilee

****updated on 8 Oct 09

On the note of Ghogilee, i found a few errors which i would like to point out. Double hashing here is referring to two different hash function.  It does reduce the search space but doesn't *greatly* increased the odds of a hash collision.  On the other hand, SHA-1 should be a 160-bit hash not 256-bit and not only does this doesn't increased the security but also weaken the hash function as the hacker will only required to crack the weaker hash function in this case md5.

If you wish to understand the risk and stuff you can do with hash function, please visit Enhance Security Hash Function For Web Development. Here i document the most detail hash function i could for your information.

Enhance Hashing With Salt

Once you have decide your secure password encryption algorithm, the last thing you might want is to have different user having the same cryptographic hash code in order to defend against rainbow attack. This can bring another problem of more than one account being compromised at the same time when there are multiple same hash and short password can easily be cracked with ease when your database and tables have been known. We can generate a salt in order to overcome this problem so that the string is longer and more random (providing that the salt + password are random enough).

define('SALT_LENGTH', 15);
function HashMe($phrase, &$salt = null)
{
$key = '!@#$%^&*()_+=-{}][;";/?<>.,';
    if ($salt == '')
    {
        $salt = substr(hash('sha512',uniqid(rand(), true).$key.microtime()), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return hash('sha512',$salt . $key .  $phrase);
}

The above function contains two parameter. The first will take in a phrase and generate a SHA-2 salt only if the second parameter is placed with an empty variable. However, if both parameter contains values, it will be used when you wish to compare between two hashes. We can use the above method this way,

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$hashed_password = HashMe($password, $salt);
$sqlquery = 'INSERT INTO  `usertable` ("username", "password", "salt") VALUES  ("'.$username.'", "'.$hashed_password .'", "'.$salt.'") WHERE 1';
..

The above will insert the information into the table when user is being created. We will check the user with the following salt.

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$sqlquery = 'SELECT `salt`, `password` FROM  `usertable` WHERE `username` = "'.$username.'" limit 1';
..
#we get the data here and placed into variable $row
$salt = $row['salt'];
$hashed_password = HashMe($password, $salt);
if($hashed_password  == $row['password']){
#verified
}
else{
#ACCESS DENIAL
}
..

The objective of salt is to lengthen the password in the table and also creates totally random hash code for each password. Furthermore, a key is being placed in as hash value to protect the password as our SALT is placed in the table and if our table is compromised, the SALT will also be take into consideration in a rainbow table. Therefore, an additional key is required that is not placed within the table. This way, even if your table is being compromised, it will really takes a lot of time for them to crack those hashed password. As i mention earlier, database can be easily compromised due to employee or social engineering.

Summary

Many of us should start moving forward to new hash function rather than sticking on to MD5 and SHA-1. Although it is still secure for these two algorithm to be used given a strong password. Nonetheless, in the near future these two might not be that secure anymore. Furthermore, both algorithm had already been dropped by US and focus on SHA-2 instead. On the other hand, SALT can really help in many ways against social engineering and inside job attack. Its not all about Session attack, SQL Injection, XSS or XRSF nowadays.

Use PHP To Check Whether Remote URL, Email Or Image Link Exist

In PHP, we have a built-in function file_exist that can help us to verify whether a particular file exist in our directory. However, do you ever have the need to check whether a particular URL, email or image link exist? We can use regular express to validate that the syntax of an email is correct but won't it be nice to reduce the amount of spam mail received? How about those images you have on your site? Won't you want to check whether there is a broken image or url link? Well, i have! Its always good to be informed in advance than meeting dissatisfy visitors. Anyway, in this article you will get to find and learn some of the more efficient and quicker ways to verify whether a particular link exist to use on your web application.

Check Remote Image Link Exist

There are many ways to check whether a particular image link exist after the introduce of PHP 5, GetImageSize. GetImageSize allows us to take in a remote link to retrieve the size of the image. Hence, we can do a simple check such as the one shown below,

$external_link = 'http://www.example.com/example.jpg';
if (@GetImageSize($external_link)) {
echo  "image exists ";
} else {
echo  "image does not exist ";
}

The above work well for any server that had GD installed. But there are more problem than just the one mention. This method is actually inefficient as it will download the entire image into your server before checking it. Thus, making the process very long. There might also be security risk as mention on Secure File Upload Check List that many image format allow comment to be embedded within the image and these comment might just be some PHP code that hacker has written. In short, this method download file from remote server to your server and take the risk of hacker using it to run malicious code after it has been downloaded on your server. BOMB! So if you are using the above method i advice you to change it and if you insist to use this, you can provide more validation checking for it. Just drop it.

So how do we check Image link in a more secure and quick environment? If you are using curl, you can try the following script:

function checkRemoteFile($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    // don't download content
    curl_setopt($ch, CURLOPT_NOBODY, 1);
    curl_setopt($ch, CURLOPT_FAILONERROR, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if(curl_exec($ch)!==FALSE)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Like i said, this will depend on curl. However, it is secure and quick! How about the rest of us? Lucky, PHP also provides another method called file_get_contents. file_get_contents returns the file in a string, starting at the specified offset up to maxlen bytes. On failure, file_get_contents() will return FALSE. With these in mind we can create a function to check that the file downloaded is valid by taking only 1 bytes of information from the file. Hence, whatever evil things exist on the file will only be able to run 1 byte and furthermore the function returns a string where code cannot be run. Thus, this will gives us a simple solution such as the one below,

function url_exists($url) {
if(@file_get_contents($url,0,NULL,0,1))
{return 1;}
else
{ return 0;}
}

The above one is more secure than the initial one that we have and it has no dependency. The speed for this method is also faster than the initial one. But is there a faster one than the curl version?

Check For Remote URL Link

There are many ways to check whether a remote url link exist. However, checking Remote URL required the page to return certain header code to indicate that the page is successfully loaded (200). Hence, you might not want to use the method for checking image link for url link. Furthermore, For different cases you might be interested with different solution. Assuming you are just checking whether an existing domain exist, you can use the following code

function url_exists($url){
    if(strstr($url,  "http:// ")) $url = str_replace( "http:// ",  " ", $url);
    $fp = @fsockopen($url, 80);
    if($fp === false) return false;
    return true;
}

which is written by adam at darkhousemedia dot com. The above method definitely run faster than fopen but for https and domain names but for path url such as 'http://example.com?p=231', the above won't work although the speed is definitely one of the fastest.

Nonetheless, there are still better alternative than the one presented. We can just tried to check the header with the following code:

function url_exists($url){
     if ((strpos($url,  "http ")) === false) $url =  "http:// " . $url;
     if (is_array(@get_headers($url)))
          return true;
     else
          return false;
}

The above work perfectly without the need to worry about complex code. However, the above method only work for HTTP and PHP 5 and above, other lower version of PHP will not. Therefore, we will need some modification on the above method to cater for lower PHP version.

function is_valid_url($url)
{
    $url = @parse_url($url);
    if (!$url)
    {
        return false;
    }
    $url = array_map('trim', $url);
    $url['port'] = (!isset($url['port'])) ? 80 : (int)$url['port'];
    $path = (isset($url['path'])) ? $url['path'] : '';
    if ($path == '')
    {
        $path = '/';
    }
    $path .= (isset($url['query'])) ?  "?$url[query] " : '';
    if (isset($url['host']) AND $url['host'] != gethostbyname($url['host']))
    {
        if (PHP_VERSION  >= 5)
        {
            $headers = get_headers( "$url[scheme]://$url[host]:$url[port]$path ");
        }
        else
        {
            $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);
            if (!$fp)
            {
                return false;
            }
            fputs($fp,  "HEAD $path HTTP/1.1\r\nHost: $url[host]\r\n\r\n ");
            $headers = fread($fp, 4096);
            fclose($fp);
        }
        $headers = (is_array($headers)) ? implode( "\n ", $headers) : $headers;
        return (bool)preg_match('#^HTTP/.*\s+[(200|301|302)]+\s#i', $headers);
    }
    return false;
}

The code here is the more detail version of the previous one which is created by SecondV on forums Dot digitalpoint Dot com. The above code cater for lower PHP version while still using the same approach of getting the return header value. Furthermore, it also validate the URL by using the parse_url method. f_open can also be used to check remote URL link.

function image_exist($url) {
	if (@fclose(@fopen( $url,  "r "))) {
	 // true;
	} else {
	 // false;
	}
}

However, this method required allow_url_fopen to be enabled on your php.ini file or else it will fail. Furthermore, i will not prefer this method over the previous one as it seems more sense that the page return success due to header code to indicate a success.

Check Email Exist

We can't actually check whether a given email exist or not as it really depend on how the SMTP is being setup for each respective mail server. Nonetheless, we are still able to check whether a given domain exist to reduce the number of invalid ones. PHP has a function checkdnsrr which does the work nicely.

function email_exist($email) {
	list($userid, $domain) = split( "@ ", $email);
	if (checkdnsrr($domain,  "MX ")) { return true;} else { return false;}
}

Using the function above will help us to verify whether a particular domain exist to trick user that you have an email checker if they really intend to fake one. However, Windows doesn't support such function yet. Hence, we will need to create such function just for Windows server.

if(!function_exists('checkdnsrr'))
function checkdnsrr($hostName, $recType = '')
{
 if(!empty($hostName)) {
   if( $recType == '' ) $recType =  "MX ";
   exec( "nslookup -type=$recType $hostName ", $result);
   // check each line to find the one that starts with the host
   // name. If it exists then the function succeeded.
   foreach ($result as $line) {
     if(eregi( "^$hostName ",$line)) {
       return true;
     }
   }
   // otherwise there was no mail handler for the domain
   return false;
 }
 return false;
}

Once you have cater for both Linux and Windows server, you may want to create a full flag function to check on email such as the one shown below:

function check_email($email)
{
	$email_error = false;
	$Email = htmlspecialchars(stripslashes(strip_tags(trim($email)))); //parse unnecessary characters to prevent exploits
	if ($Email ==  " ") { email_error = true; }
	elseif (!eregi( "^([a-zA-Z0-9._-])+@([a-zA-Z0-9._-])+\.([a-zA-Z0-9._-])([a-zA-Z0-9._-])+ ", $Email)) { email_error = true; }
	else {
	list($Email, $domain) = split( "@ ", $Email, 2);
		if (! checkdnsrr($domain,  "MX ")) { email_error = true; }
		else {
		$array = array($Email, $domain);
		$Email = implode( "@ ", $array);
		}
	} 
	if (email_error) { return false; } else{return true;}
}

Now we know why we need to verify our email after we sign up for any particular services online! Since we cannot check whether a particular email exist, we will force to send out verification email to our user before they are able to access our portal. However, if you are interested to check through PHP forcefully, you may want to visit webdigi. They create a mail class to verify an email through checking the port of mail SMTP 25 but like i said previously it really depend on how each mail server is being design. This might not work. But we can still force user to verify their email through a simple script shown below,

function check_email($email)
{
	$email_error = false;
	$Email = htmlspecialchars(stripslashes(strip_tags(trim($email)))); //parse unnecessary characters to prevent exploits
	if ($Email ==  " ") { email_error = true; }
	elseif (!eregi( "^([a-zA-Z0-9._-])+@([a-zA-Z0-9._-])+\.([a-zA-Z0-9._-])([a-zA-Z0-9._-])+ ", $Email)) { email_error = true; }
	else {
	list($Email, $domain) = split( "@ ", $Email, 2);
		if (! checkdnsrr($domain,  "MX ")) { email_error = true; }
		else {
		$array = array($Email, $domain);
		$Email = implode( "@ ", $array);
		}
	} 
	if (email_error) { return false; } else{return true;}
}
function EmailValidation($email) {
    if (check_email($email)) {
    $domain = explode(  "@ ", $email );
        if ( @fsockopen ($domain[1],80,$errno,$errstr,3)) {
			$code =  "here we place a secret key  with the email address: $email ";
			mail($email,  "Your Verification Code ",  "Please click the following URL to verify your email:\n\n  ". $_SERVER['PHP_SELF']. "/?v=$code amp;email=$email ", "From: \ "example\ "  <[email protected] > ");
			echo  "Your account needs to be verify. We have send you an email, click the link provided and you are verified. ";
			return true;
		} else {
            return false; //if a connection cannot be established return false
        }
    } else {
        return false; //if email address is an invalid format return false
    }
} 
function EmailForm(){
    if(empty($_POST['email'])){
        echo  " <form action= ".$_SERVER['PHP_SELF']. " method='post' >
         <table border='0' >
         <tr >
         <td >Email </td >
         <td > <input name='email' type='text' id='email' / > </td >
         </tr >
         <tr >
         <td > amp;nbsp; </td >
         <td > <input type='submit' name='Submit' value='Validate' / > </td >
         </tr >
         </table >
         </form > ";
    } elseif(isset($_POST['email'])) { 
        if(EmailValidation($_POST['email'])) {
            echo  "An email has been sent to you. Please follow the instructions to activate your account. ";
        } else {
            echo  "Your email address appears to be invalid. Please try again. ";
        }
    }else elseif(isset($_GET['v'])  amp; amp; isset($_GET['email'])) {
		$clean['emai'] = $_GET['email']; //need to filter these data to be clean
		$clean['v'] = $_GET['v']; //need to filter these data to be clean
		$code =  "here we place a secret key  with the email address: $email ";
		$code = md5($code);
		if ($clean['v'] != $code) {
			echo  "The Verification Code is invalid. Please Try Again. ";
			exit(0);
		}else
		echo  "The email  ".$clean['emai']. " has been verified ";
	}else { 
        echo  "An error has occured, please contact the administrator. "; 
    }
} 
EmailForm();

Might be a bit confusing but i believe you will get the above code since its quite simple. Instead of breaking them into different pages, i sum them up on a single one.

Quick check whether link is broken

Here is another tips to check whether a link is broken.

$file = 'http://www.domain.com/somefile.jpg';
$file_headers = @get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
    $exists = false;
}
else {
    $exists = true;
}

And the same version on a curl version

function url_exists($url) {
    if (!$fp = curl_init($url)) return false;
    return true;
}

credit goes to havran @ http://www.php.net/manual/en/function.file-exists.php#74469

Summary

The above solution can help many people to verify the content that the user has entered. Remember it is not safe to trust user input and such verification can come in handle. On the other hand, this can also help us to check broken and invalid links so that we get the information we need from our users. The information above might not be solid but it is good enough for me and hoping it will work for you.