Archive

Archive for the ‘PHP’ Category

Simplified PHP Input Validation for forms

June 16th, 2009

When it comes to online forms, gathering information from the user is of utmost importance. That being said, one must ensure that the user enters the correct information in the form, especially from a security point of view…Input from users in a web form provides a direct avenue of attack into the application (just google SQL Injection).

Take a simplified, yet effective approach to input validtion with your web forms and PHP.

Take a simplified, yet effective approach to input validation with your web forms and PHP.

As far as input validation goes, most programmers prefer a proactive strategy: you determine what input you want to collect from the user (number format for ages, alpha characters for names, and so forth) and then you collect only that format, producing an error message when the user enters something else. However, some users quickly get frustrated when they have to re-enter the input again, or they can’t figure out what is causing the problem. To combat the inherent confusion of the user, why not run all input through a validation function that automatically searches for potentially harmful input, removes the offending characters, then continues to process the form? This is what we are going to do:

[php]
<?php

//When the form is submitted, our 2 form fields, username and password, will be purged of potentially harmful characters.
//In this case, the characters will be replaced with blank spaces.
if ($_POST) {

//Function to remove specific special characters
function cleanInput($text)
{
$code_entities_match = array(‘-’,'>’,'!’,'#’,'$’,'%’,'^’,'&’,'*’,'(‘,’)',’{‘,’}',’|',’:',’"’,'<’,’[',']‘,’\\’,';’,"’",’,',’/',’*',’~',’`');
$code_entities_replace = array(”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”);
$text = str_replace($code_entities_match, $code_entities_replace, $text);
return $text;
}
//Set form variables
$Username=stripslashes(cleanInput($_POST['username']));
$Password=stripslashes(cleanInput($_POST['password']));

//process your form variables as needed, as they have been sanitized with our cleanInput function.
//You can write the values to a database, send via an email script, and so forth.

}//End post
?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" id="login" name="login">

<div class="label01">Username:</div>
<input type=text size=30 name="username" maxlength=30 />

<div class="label01">Password:</div>
<input type=password size=30 name="password" maxlength=30 />
<br />
<div id="submitButton">
<button type="submit" value="submit" name="submit" >Logon</button>

</div>

</form>
[/php]

Please read the script comments to see what is taking place. This is a rudimentary approach to input validation, but it works, is simple to initialize, and it will help to keep your data safe.

Thantos PHP

LDAP and PHP login script

June 10th, 2009

Authenticating users of your web applications can be tedious, especially when your users are expected to remember multiple passwords (which can become a security vulnerability in it’s own right). That being said, integrating your login scripts with Active Directory/LDAP can be beneficial for a variety reasons: stronger passwords, fewer login credentials for your user to remember, and fewer headaches for you. Here is how we integrated LDAP with our online application authentication.

LDAP (short for Lightweight Directory Access Protocol), a directory service that runs over TCP/IP, stores information. The storage is similar to how a database stores information, but the structure is ideal for attribute-based, hierarchical structured data that does not undergo frequent changes (for example, the employees’s name, Active Directory group membership, address, and so forth). The LDAP directory can be thought of as a tree of nodes, where each node represents an entry in the LDAP database. These entries are comprised of a collection of attribute-value pairs, and they are identified uniquely by a ‘distinguished name’ or DN. The DN is important, because this is what we will be using to determine a user’s group membership.
Our login script will

  1. First bind to our LDAP server with a resource account (we are not using anonymous binding, so we will need to provide a resource account’s credentials)
  2. Check that the user’s ID and password are legit and exist in our Active Directory environment
  3. Check if the user is a member of a particular security group

If all of these conditions are met, the users will have successfully logged on and will be granted access to our application.

We will store our authentication function in a php file entitled resourceBind.php. The entire contents of resourceBind.php:
[php]<?php

function UMldap($Username, $SSO_Password){
//*************************************
///////////////////////////////// Using ldap bind
$ldaprdn = ‘bindaccountname’; // ldap rdn or dn
$ldappass = ‘bindaccountpassword’; // associated password
$ldapserver = ‘ldaps://your.ldap.server:3269′;

//This is the Active Directory group that users MUST be a member of in order to login successfully
$groupPath1 = "CN=YOURSECURITYGROUP-GS,OU=Accounting,OU=Lewis-Building,OU=Headquarters,DC=headquarters,DC=acme,DC=com";

/////////////////////////////Base DN
$ldap_base_dn = "CN=Users,DC=headquarters,DC=acme,DC=com";

$ldapconn = ldap_connect($ldapserver)or die("Could not connect to LDAP server.");

if ($ldapconn) { //connect to ldap server
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
// echo "LDAP bind successful…";
$errorCount = 0;

$ld_filter = "samaccountname=" . $Username;
$ldap_base_dn = "DC=com";
//Recursively search for the account name in the directory tree. Slow, but effective…
$result = ldap_search($ldapconn, $ldap_base_dn, $ld_filter);

//Create result set
$entries = ldap_get_entries($ldapconn, $result);

//If the account exists, attempt a bind with it. This will ensure that the provided password is legit

$bind = @ldap_bind($ldapconn, $entries[0][dn], $SSO_Password);
if( !$bind || !isset($bind))
{
//the bind failed, which means that the user could have typed in the wrong ID or password. We will display another login form
?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" id="login" name="login">
Username: <input type=text size=30 name="ssoname" maxlength=30 /><br />
Password: <input type=password size=30 name="ssopass" maxlength=30 /><br />
<button type="submit" value="submit" name="submit" >Logon</button>
</form>
<?php
//no point in running the rest of the function, so exit out.
exit;

}

$ii=0;
for ($i=0; $ii < $entries[$i]["count"]; $ii++)
{

$data = $entries[$i][$ii];

if ($data == "memberof") {

$total_memberof = count($entries[$i][$data]);

$jj=0;
for ($jj=0; $jj<$total_memberof; $jj++) {

//Check the groups that the user is a member of and see if our specific group is in the list
if ($entries[$i][$data][$jj] == $groupPath1)
{
// The user is a member of the group, so lets create a session and then return true
$_SESSION['USERGROUP'] = $entries[$i][$data][$jj];
return true;
break;

}
}//end for
}//end if
}//end for
} else { //could not bind, so display an error message and the login form
// We could not bind with our default resource account, so let’s exit and not waste any time with the users credentials
$displayForm=true;
}

}///close connect IF
//Unbind from our resource account
ldap_unbind($ldapconn);

//*************************************

}//end function

?>
[/php]

And, our login page, which we will call login.php, and which will be located in the same directory as resourceBind.php:
[php]<?php
//Disable error messages
error_reporting(0);
?>
<?php require_once(‘resourceBind.php’); ?>
<?php
if ($_POST) {

//Handy function to remove specific special characters from user provided input. ALWAYS validate user input. In this case, we are removing characters that are not allowed in usernames and passwords.
function cleanTxt($text)
{
$code_entities_match =

array(‘–’,'>’,'&quot;’,'!’,'#’,'$’,'%’,'^’,'&’,'*’,'(‘,’)',’{‘,’}',’|',’:',’"’,'<’,’[',']‘,’\\’,';’,"’",’,',’/',’*',’~',’`');
$code_entities_replace = array(‘-’,'-’,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”);
$text = str_replace($code_entities_match, $code_entities_replace, $text);
return $text;
}
//Set form variables
$Username=stripslashes(cleanTxt($_POST['ssoname']));
$SSO_Password=stripslashes($_POST['ssopass']);

//Get Ip Address and User Agent information. This is useful info to store in sessions, or a database table, especially if you need to track timestamps and access
$userIP = $_SERVER['REMOTE_ADDR'];
//Get Timestamp
$myDate = date("Y-m-d H:i:s");//Date in easy-to-read format

$displayForm=false;

if(UMldap($Username,$SSO_Password)){
//set complex string in case there is no ‘whencreated’ field for the username

//User has valid credentials. We are creating a new session variable with the user name. This is also a good place to effectively double up your authentication security by checking to see if the user name exists in another medium, such as a MySQL or Oracle table.
$_SESSION['USERCMS'] = $Username;

//The login is a smashing success, so redirect the user to the protected page.
$MM_redirectWithSuccess = "Successful_login.php";
header("Location: ". $MM_redirectWithSuccess );

} else {
/We can’t log the user in, so display the login form again
$displayForm=true;
}

//unbind
ldap_unbind($ldapconn);

//*************************************
}//end POST check

?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >

<head>
<title>LDAP Login Form</title>
</head>
<body>
<h1>Login</h1>
<?php

//—————————————————————————-
//Form variables to display previously filled out fields
$displayForm=true;
$ssoname=”;
$ssopass=”;
//—————————————————————————-

//Display the login form
if ($displayForm){//Display the request form
?>

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" id="login" name="login">

UserID:
<input type=text size=30 name="ssoname" maxlength=30 />

Password:
<input type=password size=30 name="ssopass" maxlength=30 />
<br />

<button type="submit" value="submit" name="submit" >Logon</button>

</form>

<?php
}
?>

<!– Javascript to move the cursor to the Username form field. This is a small convenience to the user. –>
<script type="text/javascript" language="JavaScript">
document.forms['login'].elements['ssoname'].focus();
</script>

</body>
</html>
[/php]

To figure out how everything works, please read the comments within the code. If you are interested in learning more, please check out Hugh’s excellent book:

Thantos PHP

Regular expression searches in HTML code

May 15th, 2009

A lot of times, we have to parse an .html page and return the contents between 2 div tags.  The easiest way to do this is by using regular expressions.  This is a great way to load pages into a Content management system: using a programming language, such as PHP [what we use], you can grab the “meat and potatoes” of your content, load it in an editor (such as TinyMCE), and allow users to edit content without messing up the structure of your page.

Let’s say that we only want to grab the content between our <content01> div tag.  Here is what the PHP code looks like:

[php]$regex_pattern = "/<div class=\"content01\">(.*)<\/content01>/s";
preg_match($regex_pattern,$text,$matches);
$contentVar= $matches[0];[/php]

The first line of code creates a regular expression pattern to search for all content contained between the content01 opening and closing tags.  The second line  uses PHP’s preg_match function to search for anything that matches the pattern, with the $text variable, and save it to an array entitled $matches.  We then set a new variable, called $contentVar,  to match our result.  Pretty simple, huh?

One caveat: reg expressions can be greedy; they will try to grab as much of the matching content as possible.  That being said, the above method works best when using unique content.  For example: if you are wanting to just return  all of the links within a web page, using the above code will not work, as it will return everything associated with the links.  A new expression will better serve our purposes for this scenario:

[php]$regex_pattern = "/<a href=\"[^\"]+">[^<]+</a>/s";[/php]

Now, we can limit the scope of our search to finding at least one of any character except a double-quote, then finding the first instance of a double quote, and then a >.

Piece of cake, right? If you are hungry for more info, check out this excellent book:

Thantos PHP