PHP Security Pt 2

PHP SecurityIn this PHP Security Video tutorial I continue to show you how hackers break into web applications and how to better secure your site. If you missed part 1 of this tutorial definitely watch it first here PHP Security.

Specifically in this tutorial I will show you how SQL Injection works. Don’t do this on any site that you don’t own! I then go over all of the following:

  • Limit What Hackers can Enter in your Input Fields
  • Create Encrypted Activation Codes
  • Validate Input Data
  • Verify Email Addresses
  • How to Act Abnormally and Confound Hackers

All of the code follows the video. If you have any other questions or comments leave them below. Feel free to use the code however you like, but I’m not stating that it is 100% secure. The fact is all code can eventually be cracked. The goal is to make the code so complicated that hackers just give up and move on to an easier target.

Code From the Video

Register.PHP Code

<!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” lang=”en” xml:lang=”en”>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=ISO-8859-1″ />

<title>Registration</title>

</head>

<body>

<div id=”main”>

<?php
require_once(“./includes/confighamdb.php”);

if (isset($_POST[‘submitted’])) { // Handle the form.

if (preg_match (‘%^[A-Za-z\.\’ \-]{2,15}$%’, stripslashes(trim($_POST[‘first_name’])))) {

$fn = escape_data($_POST[‘first_name’]);

} else {

$fn = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter your first name!</font></p>’;

}

// Check for a last name.

if (preg_match (‘%^[A-Za-z\.\’ \-]{2,30}$%’, stripslashes(trim($_POST[‘last_name’])))) {

$ln = escape_data($_POST[‘last_name’]);

} else {

$ln = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter your last name!</font></p>’;

}

// Check for an email address.

if (preg_match (‘%^[A-Za-z0-9._\%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$%’, stripslashes(trim($_POST[’email’])))) {

$e = escape_data($_POST[’email’]);

} else {

$e = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter a valid email address!</font></p>’;

}

// Check for a street.

if (preg_match (‘%^[A-Za-z0-9\.\’ \-]{5,30}$%’, stripslashes(trim($_POST[‘street’])))) {

$s = escape_data($_POST[‘street’]);

} else {

$s = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter your street address!</font></p>’;

}

// Check for a city.

if (preg_match (‘%^[A-Za-z\.\’ \-]{2,25}$%’, stripslashes(trim($_POST[‘city’])))) {

$c = escape_data($_POST[‘city’]);

} else {

$c = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter a valid city!</font></p>’;

}

// Check for a state.

if (preg_match (‘%^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$%’, stripslashes(trim($_POST[‘state’])))) {

$st = escape_data($_POST[‘state’]);

} else {

$st = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter a valid state!</font></p>’;

}

// Check for a zip code.

if (preg_match (‘%^[0-9]{5}$%’, stripslashes(trim($_POST[‘zip’])))) {

$z = escape_data($_POST[‘zip’]);

} else {

$z = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter a valid 5 digit zip code!</font></p>’;

}

// Check for a phone number.

if (preg_match (‘%^([0-9]( |-)?)?(\(?[0-9]{3}\)?|[0-9]{3})( |-)?([0-9]{3}( |-)?[0-9]{4}|[a-zA-Z0-9]{7})$%’, stripslashes(trim($_POST[‘work_phone’])))) {

$ph = escape_data($_POST[‘work_phone’]);

} else {

$ph = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter a valid phone number!</font></p>’;

}

// Check for a password and match against the confirmed password.

if (preg_match (‘%\A(?=[-_a-zA-Z0-9]*?[A-Z])(?=[-_a-zA-Z0-9]*?[a-z])(?=[-_a-zA-Z0-9]*?[0-9])\S{6,}\z%’, stripslashes(trim($_POST[‘password1’])))) {
if ($_POST[‘password1’] == $_POST[‘password2’]) {

$p = escape_data($_POST[‘password1’]);

} else {

$p = FALSE;

echo ‘<p><font color=”red” size=”+1″>Your password did not match the confirmed password!</font></p>’;
}

} else {

$p = FALSE;

echo ‘<p><font color=”red” size=”+1″>Please enter a valid password!</font></p>’;

}

if ($fn && $ln && $e && $p && $fn && $s && $c && $st && $z && $ph) {
$query = “SELECT user_id FROM users WHERE email=’$e'”;

$result = mysql_query($query) or trigger_error(“Sorry email is taken”);

if(mysql_num_rows($result) == 0) {
$a = md5(uniqid(rand(), true));

$query = “INSERT INTO users(email, pass, first_name, last_name, active, registration_date, street, city, state, zip, work_phone) VALUES (‘$e’, SHA(‘$p’), ‘$fn’, ‘$ln’, ‘$a’, NOW(), ‘$s’, ‘$c’, ‘$st’, ‘$z’, ‘$ph’)”;

$result = mysql_query($query) or trigger_error(“Sorry an error happened”);

if(mysql_affected_rows() == 1) {

$body = “Thanks for registering. Activate account by clicking this link: <br />”;

$body .= “http://localhost/activate.php?x=” . mysql_insert_id() . “&y=$a”;

mail($e, ‘Registration Confirmation’, ‘$body’, ‘From: derekbanas@verizon.net’);

echo ‘<br /><br /><h1>Thank you for registering! A confirmation email has been sent to your address. Please click on the link in that email in order to activate your account.</h1>’;

exit();

} else {

echo ‘<p><font color=”red” size=”+1″>You could not be registered due to a system error. We apologize for any inconvenience.</font></p>’;

}

} else {

echo ‘<p><font color=”red” size=”+1″>That email address has already been registered. If you have forgotten your password, use the link to have your password sent to you.</font></p>’;

}

mysql_close();
}

?>

<h1>Register</h1>

<form action=”register.php” method=”post”>

<fieldset>

<p><b>First Name:</b> <input type=”text” name=”first_name” size=”15″ maxlength=”15″ value=”<?php if (isset($_POST[‘first_name’])) echo $_POST[‘first_name’]; ?>” /></p>

<p><b>Last Name:</b> <input type=”text” name=”last_name” size=”30″ maxlength=”30″ value=”<?php if (isset($_POST[‘last_name’])) echo $_POST[‘last_name’]; ?>” /></p>

<p><b>Email Address:</b> <input type=”text” name=”email” size=”40″ maxlength=”40″ value=”<?php if (isset($_POST[’email’])) echo $_POST[’email’]; ?>” /> </p>

<p><b>Street:</b> <input type=”text” name=”street” size=”40″ maxlength=”40″ value=”<?php if (isset($_POST[‘street’])) echo $_POST[‘street’]; ?>” /> </p>

<p><b>City:</b> <input type=”text” name=”city” size=”25″ maxlength=”25″ value=”<?php if (isset($_POST[‘city’])) echo $_POST[‘city’]; ?>” /> </p>

<p><b>State:</b> <input type=”text” name=”state” size=”2″ maxlength=”2″ value=”<?php if (isset($_POST[‘state’])) echo $_POST[‘state’]; ?>” /> <small>Use only the two letter initials</small></p>

<p><b>Zip Code:</b> <input type=”text” name=”zip” size=”5″ maxlength=”5″ value=”<?php if (isset($_POST[‘zip’])) echo $_POST[‘zip’]; ?>” /> </p>

<p><b>Phone:</b> <input type=”text” name=”work_phone” size=”20″ maxlength=”20″ value=”<?php if (isset($_POST[‘work_phone’])) echo $_POST[‘work_phone’]; ?>” /> </p>

<p><b>Password:</b> <input type=”password” name=”password1″ size=”20″ maxlength=”20″ /> <small>Use only letters and numbers. Must be between 4 and 20 characters long.</small></p>

<p><b>Confirm Password:</b> <input type=”password” name=”password2″ size=”20″ maxlength=”20″ /></p>

</fieldset>

<div align=”center”><input type=”submit” name=”submit” value=”Register” /></div>

<input type=”hidden” name=”submitted” value=”TRUE” />

</form>

MySQL Connect Code

<?php
// Define these as constants so that they can’t be changed
DEFINE (‘DBUSER’, ‘mysqladm’);
DEFINE (‘DBPW’, ‘password’);
DEFINE (‘DBHOST’, ‘localhost’);
DEFINE (‘DBNAME’, ‘hamdb’);

if ($dbc = mysql_connect (DBHOST, DBUSER, DBPW)) {

if (!mysql_select_db (DBNAME)) { // If it can’t select the database.

// Handle the error.

trigger_error(“Could not select the database!<br />MySQL Error: ” . mysql_error());

exit();

} // End of mysql_select_db IF.

} else {

// Print a message to the user, and kill the script.

trigger_error(“Could not connect to MySQL!<br />MySQL Error: ” . mysql_error());

exit();

}

// A function that strips harmful data.
function escape_data ($data) {

// Check for mysql_real_escape_string() support.
// This function escapes characters that could be used for sql injection
if (function_exists(‘mysql_real_escape_string’)) {
global $dbc; // Need the connection.
$data = mysql_real_escape_string (trim($data), $dbc);
$data = strip_tags($data);
} else {
$data = mysql_escape_string (trim($data));
$data = strip_tags($data);
}

// Return the escaped value.
return $data;

} // End of function.

?>

32 Responses to “PHP Security Pt 2”

  1. Roger says:

    Appreciate this. But when I installed the code, I get

    Parse error: syntax error, unexpected $end

    with this code.

    In a previous post, you’d said, “All of my new tutorials provide links to the raw files that have been triple checked for errors.” but I don’t see a link for that here.

    HELP!

    Thanks in advance

  2. Roger says:

    Thanks. However, I apologize, I made a mistake in my email address. I’ve entered it correctly now. Would you please send it again? Thanks

  3. Oree says:

    I too would like to have the code emailed to me, if you don’t mind.

  4. Daniel Pettersson says:

    Hello! First of all thank you for a great tutorial. have a little bit of problem, which I hope you might have time to help me with πŸ™‚

    I downloaded the zip file with the php code, and began with the registration script. I removed both state and zip, from both the php code aswell as the forms.

    I made a table called users, which looks like this :


    — Struktur fΓΆr tabell users

    CREATE TABLE IF NOT EXISTS users (
    user_id int(3) NOT NULL AUTO_INCREMENT,
    email varchar(50) NOT NULL,
    pass varchar(32) NOT NULL,
    first_name varchar(30) NOT NULL,
    last_name varchar(30) NOT NULL,
    active varchar(30) NOT NULL,
    registration_date date NOT NULL,
    street varchar(30) NOT NULL,
    city varchar(30) NOT NULL,
    work_phone int(10) NOT NULL,
    PRIMARY KEY (user_id)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

    which I hope should be alright. A problem is when I try to register, and everytime it says that the password isnt valid, tried a lot of times. What could the reason be behind this?

    Thanks for the tutorials, you are doing a great job!

  5. rupesh kumar says:

    hi admin.
    i want to make a registration page and login page with following field. plz help me i tried my time but its shows error every time.

    first_name,last_name,email,password,status,actcode,address,location,photo_path,joined_date,last_login.

  6. Adam S. says:

    Hi,

    where can I find “activation.php” code?

    Regards

  7. Giorgio says:

    Hi, and thank you so much for sharing your knowledge.

    I’ve got a doubt, sorry if it’s silly but I’m not very skilled in PHP. I suppose that people clik on register.php page to register. But in the source code of this page, the address of the confighamdb.php is visible, and so everybody would know my DB passwords and data used for connection.. I know that what people see is the HTML output of the register.php page, but are there any possible ways where people see my register.php source code? Thanks in advance.

  8. Seckart says:

    Great tutorial Mr.Admin .Will it be possible to email the whole folder with the codes ?

  9. jagankumar says:

    first of all ur tutorial is very nice to freshers and i need a information abt database connection.how do i connect register form user datas into my database by using phpmyadmin.

  10. Dave says:

    Hi Derek, thanks for the tutorials. I had problems when I initially copied and pasted your code so I deleted all files and started again. I have replaced all the speech marks etc that you advised due to wordpress but when I try to use the files as they are it will not let me submit, keeps advising enter valid state which I do NY despite being in the UK but also enter a valid password which I do, for the sake of trying to get it working I was just using pass123 which I repeated in the password2 field.

    Can I just confirm that the database you used had 10 fields
    user_id int PK and AI, email, first_name, last_name, city, street, state, zip, work_phone, pass and registration_date

    I can only think that I have set something up in the dbase that it doesn’t like so if you could confirm I would be grateful.

    • Dave says:

      I meant 11 fields, sorry

      • Dave says:

        I found the form would not take NY as a state, entered Florida and it accepted that, then I managed to get it to accept a password and once pressed submit got the following

        Notice: Sorry an error happened in C:\xampp\htdocs\register\regexpressions\register.php on line 160

        This relates to

        $result = mysql_query($query) or trigger_error(“Sorry an error happened”);

        Whether the actual issue is there or not I do not know, trying to work my way through the code now. Maybe you can shed some light on it? Thanks

        • Dave says:

          Derek, before I take over your message system, just wanted to let you know, yes I realise you wrote this sometime ago, I have the script working now however as I stated previously for some reason it will not let me enter NY as the state. I have ended up with 12 fields in the database, the 12th being an enum set as default 0, is this correct. I assume that the email link that you would click on to confirm your registration would then change enum to 1?

          Thanks

    • Derek Banas says:

      I’m sorry you wasted so much time over that error on my part. Thank you for being so nice πŸ™‚

  11. imam wahyudi says:

    Dear Derek Banas,
    If I’m allowed to give some advise, I think
    you should create a tutorial that specially covers
    the preg_match() function, since there are many variables
    to consider.
    And in the information we get from the internet, all of it
    is too complicated.
    Thank you.
    Regards,
    Imam Wahyudi

    • Derek Banas says:

      Thank you Imam. I plan on covering PHP again in the future. I do have a bunch of Regex tutorials here on my site that may help. I plan on covering the ZEND framework for PHP as soon as I get the chance. I’ll keep your input for when I get back into it

  12. Steven says:

    Hi Derek,

    Thanks for sharing. Great video.

    If you have time, please explain this line:
    $result = mysql_query($query) or trigger_error(“Sorry email is taken”);

    if the line $result=mysql_query($query) doesn’t work, how can you know that the email is taken?

    • Derek Banas says:

      Thank you πŸ™‚

      It works because this query SELECT user_id FROM users WHERE email=’$e’
      Checks to see if the provided email is in the system already.

  13. imam wahyudi says:

    Dear Derek Banas,

    I have a question regarding share hosting.
    If I set the PHP, such as by ini_set() function,
    or by setting php.ini, or by setting httpd,
    will that be effecting all domains that hosted on the same server,
    or only be effecting my one domain ?

    If it is affecting all domains, then how to restrict my setting,
    so that it will be affecting only on my domain ?

    Thanks before.
    I’m looking forward to receiving your reply.
    Regards,

    Imam Wahyudi

Trackbacks/Pingbacks

  1. Tweets that mention PHP Security Pt 2 | New Think Tank -- Topsy.com - [...] This post was mentioned on Twitter by elearningstarr. elearningstarr said: PHP Security Pt 2 http://dlvr.it/D17Fj [...]

Leave a Reply

Your email address will not be published.

Google+