So, I'm trying to write a small user registration page using PHP and MySQL. I know, PHP AND MySQL, what is this? 1995? Ho ho ho!
Anyway, I'm curious as to how well I did with regards to security. Can anyone notice anything obviously apparent?
register.html :
Code:
<!DOCTYPE html>
<html>
<head>
<title>ditacms User Registration</title>
</head>
<body>
<p>Complete the registration form below</p>
<form method="post" action="register.php" id="registration_form">
<label>Username : </label>
<input type="text" name="username" />
<br/>
<label>Email : </label>
<input type="text" name="email" value="" />
<br/>
<label>Password : </label>
<input type="text" name="password" value="" />
<br/>
<label>Re-Type Password : </label>
<input type="text" name="confirm_password" value="" />
<br/>
</form>
<button type="submit" form="registration_form">Register</button>
</body>
</html>
register.php
Code:
<!DOCTYPE html>
<html>
<head>
<title>Registration Processing</title>
</head>
<body>
<?php
define( "EOL", "<br />\n" );
// data source name
define( "DSN", "mysql:host=localhost;dbname=ditacms;charset=utf8" );
define( "USER", "account_creator" );
define( "PASSWORD", "UrsaOwnsRoshan" );
function db_connect()
{
try
{
$db = new PDO( DSN, USER, PASSWORD );
}
catch( PDOException $ex )
{
// echo $ex->getMessage();
// echo $ex->getTraceAsString();
echo "Attempt to connect to database failed!" . EOL;
exit();
}
return $db;
}
function verify_post_register_params()
{
$username = $_POST[ "username" ];
$email = $_POST[ "email" ];
$password = $_POST[ "password" ];
$confirm_password = $_POST[ "confirm_password" ];
// if the user left any field blank...
if ( empty( $username ) ||
empty( $email ) ||
empty( $password ) ||
empty( $confirm_password ) )
{
echo "Empty field found in form submission!" . EOL;
echo "Please complete the form." . EOL;
return false;
}
// if the passwords do not exactly match...
if ( strcmp( $password, $confirm_password ) !== 0 )
{
echo "Password mismatch!";
return false;
}
$username = filter_var( $username, FILTER_SANITIZE_STRING );
$email = filter_var( $email, FILTER_SANITIZE_EMAIL );
$password = filter_var( $password, FILTER_SANITIZE_STRING );
if ( $username === false ||
$email === false ||
$password === false )
{
echo "Sanitization failed! Potential attack!!!" . EOL;
return false;
}
if ( filter_var( $email, FILTER_VALIDATE_EMAIL ) === false )
{
echo "Invalid email address!" . EOL;
return false;
}
$register = array( "username" => $username,
"email" => $email,
"password" => $password );
return $register;
}
function user_exists( $db, $username )
{
$query = $db->prepare( "SELECT username FROM `ditacms`.`members` WHERE username = :username" );
$query->bindValue( ":username", $username, PDO::PARAM_STR );
$query->execute();
$rows = $query->fetchAll( PDO::FETCH_ASSOC );
// if the rows returned are empty, the user
// does NOT exist so return false
if ( empty( $rows ) === true )
{
return false;
}
// if the rows returned are NOT empty, the
// user DOES exist so return true
else
{
echo "A user with that username already exists!" . EOL;
return true;
}
}
function create_new_user( $db, $username, $email, $password )
{
echo "Creating new user..." . EOL;
$insert = $db->prepare( "INSERT INTO `ditacms`.`members` (username, email, password)
VALUES(:username, :email, :password)" );
$hash = password_hash( $hash, PASSWORD_DEFAULT );
$insert->bindValue( ":username", $username, PDO::PARAM_STR );
$insert->bindValue( ":email", $email, PDO::PARAM_STR );
$insert->bindValue( ":password", $hash, PDO::PARAM_STR );
if ( $insert->execute() === false )
{
echo "Insertion failure..." . EOL;
return false;
}
else
{
echo "Successfully registered new account!" . EOL;
return true;
}
}
/*
* main() loop
*/
echo "<p>Processing user registration request...</p>";
$register = verify_post_register_params();
if ( $register === false )
{
echo "Bad POST parameters. Exiting script..." . EOL;
}
else
{
$db = db_connect();
// if the user does NOT exist, create one
if ( user_exists( $db, $register[ "username" ] ) === false )
{
create_new_user( $db, $register[ "username" ],
$register[ "email" ],
$register[ "password" ] );
}
}
?>
<a href="/ditacms.com/register.html">Return to registration page</a>
<br />
<a href="/ditacms.com/">Return to homepage</a>
</body>
</html>
I hear that SQL injections can still happen with POST data so I'm just wondering if there's anything I obviously forgot or didn't even register.
Also, the account_creator MySQL account can only SELECT, INSERT and UPDATE.