Are the variables in this code properly escaped? - php

I think I have properly escaped everything, but yet I'm wondering whether I did the right thing. I remember to read somewhere that we shouldn't filter the input, just the output. In my case, does it mean that I shouldn't use the function sanitize anywhere? And just stick to prepare statements and htmlscpecialchars?
<?php
#Connection to the database
function dbcon (){
try{
$db = new PDO('mysql:dbname=php_test;host=localhost','root','mysql');
}
catch (PDOException $e){
echo $e->getMessage();
exit();
}
return $db;
}
#Sanitize the input for preventing hacking attempts
function sanitize($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
#Get the list of countries from the DB
function getCountries() {
$db = dbcon();
$query = "SELECT country FROM countries";
$stmt = $db->prepare($query);
$stmt->execute();
$countries = "";
while ($row = $stmt->fetch()) {
$countries .= '<option value= "'.$row['country'].'">'.$row['country'].'</option>';
}
return $countries;
}
$name = $email = $password = $password2 = $country = "";
$validForm = True;
#If it's a submission, validate the form
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$db = dbcon();
#Name validation
$name = sanitize($_POST["name"]);
if ((strlen($name) < 2) || (strlen($name) > 50)) {
echo "<span style=\"color: #FF0000;\"> Name must have between 2 and 50 characters </span> <br>";
$name = "";
$validForm = False;
}
#Email validation
$email = sanitize($_POST["email"]);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "<span style=\"color: #FF0000;\"> Check the format of the email </span> <br>";
$email = "";
$validForm = False;
}
else { #If it's a valid email, check whether or not it's already registered
$query = "SELECT email FROM users;";
$stmt = $db->prepare($query);
$stmt->execute();
$found = False;
while (($row = $stmt->fetch()) and (!$found)) {
if ($row["email"] == $email) {
$found = True;
}
}
if ($found) {
echo "<span style=\"color: #FF0000;\"> This email is already registered </span> <br>";
$email = "";
$validForm = False;
}
}
#Password validation
$password = sanitize($_POST["pass1"]);
if ((strlen($password) < 6) || (strlen($password) > 20)) {
echo "<span style=\"color: #FF0000;\"> Password must have between 6 and 20 characters </span> <br>";
$validForm = False;
}
else { #If it's a valid password, check whether or not both passwords match
$password2 = sanitize($_POST["pass2"]);
if ($password != $password2) {
echo "<span style=\"color: #FF0000;\"> Passwords don't match </span> <br>";
$validForm = False;
}
#If passwords match, hash the password
else {
$password = password_hash($password, PASSWORD_DEFAULT);
}
}
#We don't need to validate country because it's retrieved from the DB, but we sanitize it just in case a hacker modified the POST using a proxy
$country = sanitize($_POST["country"]);
#All checks done, insert into DB and move to success.php
if ($validForm) {
$query = "INSERT INTO users VALUES(:name, :email, :password, :country);";
$stmt = $db->prepare($query);
$stmt->bindParam(':name', $name);
$stmt->bindParam(':email', $email);
$stmt->bindParam(':password', $password);
$stmt->bindParam(':country', $country);
$stmt->execute();
header("Location: success.php");
}
}
?>
<html>
<head>
</head>
<body>
<!-- Submitting to this very file -->
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<table>
<tr> <!-- Name -->
<td><label for="name">Name:</label></td>
<td><input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>" required /></td>
<td><span style="color: #FF0000;">*</span></td>
<td>Between 2 and 50 characters</td>
</tr>
<tr> <!-- Email -->
<td><label for="email">Email:</label></td>
<td><input type="text" name="email" value="<?php echo htmlspecialchars($email); ?>" required/></td>
<td><span style="color: #FF0000;">*</span></td>
<td>Must be a valid address</td>
</tr>
<tr> <!-- Password -->
<td><label for="pass1">Password:</label></td>
<td><input type="password" name="pass1" required/></td>
<td><span style="color: #FF0000;">*</span> </td>
<td>Between 6 and 20 characters</td>
</tr>
<tr> <!-- Confirm password -->
<td><label for="pass2">Confirm password:</label></td>
<td><input type="password" name="pass2" required/></td>
<td><span style="color: #FF0000;">*</span></td>
<td>Must be the same as the password</td>
</tr>
<tr> <!-- Country -->
<td><label for="country">Country:</label></td>
<td><select name="country"> <?php echo getCountries(); ?></select></td>
<td><span style="color: #FF0000;">*</span></td>
</tr>
<tr>
<td><input type="submit"></td>
</tr>
</table>
</form>
</body>
</html>

Its all done with PDO::prepare
Calling PDO::prepare() and PDOStatement::execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information, and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters.
and there is anther alternate
PDO::quote
PDO::quote() places quotes around the input string (if required) and escapes special characters within the input string, using a quoting style appropriate to the underlying driver.
To know about XSS Injection Read this Answer too

One thing I always use when cleaning data entered by the user is to use strip_tags()...
Specially if the content is to be echoed at some point... you dont want to make easy to inject scripts using your forms.
Try to type <script>alert("hello");</scirpt> in one of the text element and submit...

Related

PHP form validation and XSS security

Am new to php and am taking a web application development to allow come across different skill, problems and find a way to fix them.
Am now creating a registration form and validating the form and protecting it against SQL Injection and XSS. NOTE I understand could have use prepared statement, but for my level of skill i think starting from Mysqli procedural wold be best result for my development until if fill confident enough.
So i just want you the expert to see if there is something i needed to remove or add or use instead (apart from stmt).
Here is my Register page.
<?php
// define mqsqli real escape string function
function _olaskee($escape) {
$escape = htmlspecialchars ($escape, ENT_QUOTES, 'UTF-8');
$escape = trim ($escape, ENT_QUOTES, 'UTF-8');
$escape = stripcslashes ($escape, ENT_QUOTES, 'UTF-8');
return $escape;
}
// start session
session_start();
// include database connection
//require_once('include/connection.php');
// if user type already detected, redirect to index.php
if(isset($_SESSION['user_type'])){
header('Location: index.php');
}
// check if we have submited / if the for as being submitted
if(!empty($_POST['submit'])){
//instantiate
$firstname = _olaskee($con, $_POST['firstname']);
$lastname = _olaskee($con, $_POST['lastname']);
$user_name = _olaskee($con, $_POST['user_name']);
$user_type = _olaskee($con, $_POST['user_type']);
$password = _olaskee($con, $_POST['password']);
$confirm_password = _olaskee($con, $_POST['confirm_password']);
// hash password
$hashed_password = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
// include database connection
require_once('include/errMsg.php');
}
// include page title
$title = 'Registration Page';
// include header layout
require_once('include/header.php');
?>
<div>
<form name="register" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>" method="post">
<table>
<tr>
<td>First Name</td>
<td><input type="text" name="firstname" value='<?php// echo htmlspecialchars ($firstname) ?>'><br><span style='color: red'><?php echo $fnErr ?></span></td>
<?php echo $firstname ; ?>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="lastname" value='<?php echo htmlspecialchars ($lastname) ?>'><br><span style='color: red'><?php echo $lnErr ?></span></td>
</tr>
<tr>
<td>User Name</td>
<td><input type="text" name="user_name" value='<?php echo htmlspecialchars ($user_name) ?>'><br><span style='color: red'><?php echo $unameErr ?></span></td>
</tr>
<tr>
<td>User Type</td>
<td>
<!-- <label for="flavor">Select User Type:</label > -->
<select id="user_type" name='user_type' >
<option value="">Select User Type</option>
<option <?php echo $user_type=='rsw'?'selected':''; ?> >rsw</option>
<option <?php echo $user_type=='sp'?'selected':''; ?> >sp</option>
</select>
<span style='color: red'><?php echo $u_typeErr?></span>
</td>
</tr>
<tr>
<td>Email</td>
<td><input type="email" name="email" value='<?php echo htmlspecialchars ($email) ?>'><br /><span style='color: red'><?php echo $emailErr ?></span></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" id="password"><br /><span style='color: red'><?php echo $passErr ?></span></td></td>
</tr>
<tr>
<td>Confirm Password:</td>
<td><input type="password" name="confirm_password" id="confirm_password"><br /><span style='color: red'><?php echo $cpassErr ?></span></td></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="submit" value="Register"><a href='index.php'> Login</a></td>
</tr>
</table>
</form>
</div>
<?php
if(is_file('include/footer.php'))
include_once('include/footer.php');
?>
And here is my error message page
<?php
// error handler variable
$fnErr = $lnErr = $unameErr = $u_typeErr = $emailErr = $passErr = $cpassErr = '';
$firstname = $lastname = $user_name = $user_type = $email = $password = $confirm_password = '';
// if submit, then validate
$firstname = ($_POST['firstname']);
// set field validation for first name
if (empty($firstname)){
$fnErr = 'Field empty, please enter your first name';
}else{
if (strlen($firstname) < 3){
$fnErr = 'First Name is too short';
}
}
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z ]*$/",$firstname)) {
$fnErr = "Only letters and white space allowed";
}
// set field validation for last name
$lastname = ($_POST['lastname']);
if (empty($lastname)){
$lnErr = 'Field empty, please enter your last name';
}else{
if (strlen($lastname) < 3){
$lnErr = 'Last Name is too short';
}
}
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z ]*$/",$lastname)) {
$lnErr = "Only letters and white space allowed";
}
// set field validation for user name
$user_name = ($_POST['user_name']);
if (empty($user_name)){
$unameErr = 'Field empty, please enter user name';
}else{
if (strlen($user_name) < 6){
$unameErr = 'Password is too short';
}else{
if (strlen($user_name) > 15){
$unameErr = 'Password is too long';
}
}
}
// check if name only contains letters and whitespace
if (!preg_match("#.*^(?=.*[a-z])(?=.*[A-Z]).*$#",$user_name)) {
$unameErr = "At least one CAPS, letters and white space allow";
}
// check if user select user type from list
$user_type = ($_POST['user_type']);
if (empty($user_type)){
$u_typeErr = 'Please select user type from list';
}
// set email filter validation
$email = ($_POST['email']);
if (empty($email)){
$emailErr = 'Field empty, please enter your last name';
}else{
// check if e-mail address is well-formed
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Invalid email format";
}
}
// set field validation for password
$password = ($_POST['password']);
if (empty($password)){
$passErr = 'Field empty, please create a password';
}else{
if (strlen($password) < 6){
$passErr = 'Password is too short';
}else{
if (strlen($password) > 15){
$passErr = 'Password is too long';
}
}
}
if( !preg_match("#[A-Z]+#", $password) ) {
$passErr = "Password must include at least one CAPS! ";
}else{
if( !preg_match("#[0-9]+#", $password) ) {
$passErr = "Password must include at least one NUMBER! ";
}
}
// // // check if name only contains letters and whitespace
// if (preg_match("#.*^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$#", $password)) {
// $passErr = "Try again... Password must contain NUMBER, LETTER and CAPS";
// }
// set field validation for confirm password
$confirm_password = ($_POST['confirm_password']);
if (empty($confirm_password)){
$cpassErr = 'Field empty, please confirm your password';
}else{
if ($password != $confirm_password) {
$cpassErr = 'Error... Passwords do not match';
}
}
// // define mqsqli real escape string function
// function _olaskee($escape) {
// $escape = htmlspecialchars ($escape, ENT_QUOTES, 'UTF-8');
// $escape = trim ($escape, ENT_QUOTES, 'UTF-8');
// $escape = stripcslashes ($escape, ENT_QUOTES, 'UTF-8');
// return $escape;
// }
?>
NOTE have commented out some lines in both pages.
Also in the register page have include the security function at the top of the session unsure if that's right.
Also have used the password hashing, but i haven't test in on database yet, but (have i used it right?)
Please just have a look and give me your expert opinion
Best Regards
I am not an expert but I can give you some notes. In your sanitizing function _olaskee, I think you need to understand what these functions does and how to use it
You don't need stripcslashes here. This function removes the slashes why are you putting it here?
You don't need to sanitize the password. You will be hashing it before using it and hashing will replace any injected code
For sanitizing against SQL Injection you need to use mysqli_real_escape_string It will take care of sanitizing strings.
Take a look at filter_var function. You will find it very useful in sanitizing and validating your inputs. This function allows you to validate against a specified length, allow some HTML tags in certain inputs (like textarea) and so on
To understand how to protect yourself from attacks you need to know first how the attacks are made. Read about SQL Injections and see if you can hack your database through vulnerable code.
You may try also try ZAP tool. You can use automatic scan by just passing the URL of your site and it will automatically scan your web app and report any vulnerabilities it finds
It is good to learn how to make a login system. But for real world applications, it is not advised to make your own login system. Always rely on tested and approved software or you will be creating systems full of vulnerabilities. Good luck!

PHP Form Validation assistant

I really need a help. I know there are similar help with my, but have tried them out no luck.
Am creating a Registration system with user type using PHP and Mysqli procedural. Am just starting up with PHP so please bear with me.
I need help with form validation... it looks OK to me, but the error is not processing. Below is my register and errMsg code.
Connection Code:
define('HOST','localhost');
define('USERNAME','');
define('PASSWORD','');
define('DBNAME','');
$con=mysqli_connect(HOST,USERNAME,PASSWORD,DBNAME)or die('ERROR WHILE CONNECTING TO DATABASE SERVER');
?>
Registration and errMsg code
<?php
session_start();
if(is_file('include/connection.php'))
include_once('include/connection.php');
else
exit('Database FILES MISSING:(');
?>
<?php $_SESSION['main_title'] = "Registration Page"; ?>
<?php
if(isset($_SESSION['user_type'])){
header('Location: index.php');
}
if(isset($_POST['submit']))
{
extract($_POST);
// $name = $_POST["name"];
// $email = $_POST["email"];
// $password = $_POST["password"];
// $name = mysqli_real_escape_string($con, $name);
// $email = mysqli_real_escape_string($con, $email);
// $password = mysqli_real_escape_string($con, $password);
$created_at = date('Y-m-d');
$queryInsert = "insert into user (name,last_name,user_name,user_type,email,password,created_at) values ('$name','$last_name','$user_name','$user_type','$email','$password','$created_at')";
$resInsert = mysqli_query($con,$queryInsert);
if($resInsert){
$_SESSION['main_notice'] = "Successfully registered, login here!";
header('Location: index.php');
}else{
$_SESSION['main_notice'] = "Some error, try again";
header('Location: '.$_SERVER['PHP_SELF']);
}
}
?>
<?php
if(is_file('include/header.php'))
include_once('include/header.php');
?>
<?php
// define variables and set to empty values
$nameErr = $lnameErr = $userErr = "";
$name = $lname = $user = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// validate first name
if (empty($_POST["name"])) {
$nameErr = "first Name is required";
}else {
$name = test_input($_POST["name"]);
}
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
$nameErr = "Only letters and white space allowed";
}
// validate last name
if (empty($_POST["lname"])) {
$lnameErr = "Last Name is required";
}else {
$lname = test_input($_POST["lname"]);
}
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z ]*$/",$lname)) {
$lnameErr = "Only letters and white space allowed";
}
// validate user type
if (empty($_POST["user_name"])) {
$userErr = "Last Name is required";
}else {
$user = test_input($_POST["user_name"]);
}
// check if name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z ]*$/",$user)) {
$userErr = "Only letters and white space allowed";
}
}//end validate tag
?>
<div>
<form name="register" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post" onsubmit="return check()">
<table>
<tr>
<td>Name</td>
<td><input type="text" name="name" value='<?php echo $name ?>'><span style='color: red'>* <?php echo $nameErr;?></span>
</td>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="last_name" value='<?php echo $lname ?>'><span style='color: red'>* <?php echo $lnameErr;?></span></td>
</tr>
<tr>
<td>User Name</td>
<td><input type="text" name="user_name" value='<?php echo $user ?>'><span style='color: red'>* <?php echo $userErr;?></span></td>
</tr>
<tr>
<td>User Type</td>
<td>
<select name="user_type" >
<option value="member">Member</option>
<option value="leader">Leader</option>
</select>
</td>
</tr>
<tr>
<td>Email</td>
<td><input type="email" name="email" ></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" id="password" ></td>
</tr>
<tr>
<td>Confirm Password:</td>
<td><input type="password" name="confirm_password" id="confirm_password" ></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="submit" value="Register"></td>
</tr>
</table>
</form>
</div>
<script>
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
// function check(){
// if(document.getElementById('password').value != document.getElementById('confirm_password').value ){
// alert('password not match');
// return false;
// }else{
// return true;
// }
// }
</script>
<?php
if(is_file('include/footer.php'))
include_once('include/footer.php');
?>
Am not sure if am missing something, but when i send the form without any input, it process it on database. And if i put input in just name field, it just refresh and go blank, even the value data doesn't work idea.
I hope have given enough information for your help, please if any question do ask me.
Thanks in advance
The order of your code seems like it may be the issue. You are checking if the $_POST['submit'] is set and then performing your database operations before the section of code which carries out validation. The section which sets the values to empty should come first, the you want to check if $_POST['submit'] is set, and if it is you THEN do the validation within the if statement. So quickly in pseudocode:
include PHP files
check if user is already logged in
initialise variables
if submit is set {
Validate the input
if valid {
Submit to database
} else {
return error messages as needed
}
}
I hope this helps
EDIT:
$stmt = $con->prepare("INSERT INTO user (name, last_name, user_name, user_type, email, password, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("sssssss", $name, $last_name, $user_name, $user_type, $email, $password, $created_at);
$stmt->execute();
$stmt->close();
$con->close();
Also, noticed a few more issues with your other code which may cause you problems.
In the input checks, you are setting variables like $nameErr if the field is invalid. Once you've sorted the code order out though you may find that you have to introduce a check for whether or not you actually have an error at the end of the validation or it will attempt to execute the database section anyway.
The error variables are echo'd to the page but if the all the inputs were acceptable, none of these variables will be defined and PHP might throw errors
Reorganise the code, and then have a careful look at it and think about how the data flow would work when valid and invalid (or null) input is provided.

Error on bindValue

I already browsed the Internet, but could not find and understand any solution provided.
Basically, I created (or rather copied some scripts from the Internet) and tried to work on the scripts to make a registration page. I'm using PHP, Mysql and XAMPP. The connection is fine already.. I tested some data inputs on a basic form etc.
but My problem is, after I messed around with the scripts, I managed to insert data into the table (peekdoordb)...all the hashing and validation form worked..except that, the form keeps submitting data into the DB even when data is wrong or the field is empty. After I messed around again, then the problem arises. The error is on " $stmt->bindValue(':name', $name);"
I keep getting this error on browser;
Notice: Undefined variable: stmt in C:\xampp\htdocs\eventsite\TMP1kjqc3x.php on
line 194
and
Fatal error: Call to a member function bindValue() on a non-object in C:\xampp\htdocs\eventsite\TMP1kjqc3x.php on line 194
The registration.php (registration page) include 2 files which are connect.php and password.php but I never messed anything with those 2 files, because before that, data could be submitted only the problem was with the form, data keeps inserting in DB like I mentioned previously. But the main problem now is about this error.
<?php
//register.php
/**
* Start the session.
*/
session_start();
//Include password_compat library.
require 'lib/password.php';
//Include MySQL connection.
require 'connect.php';
//define variables and define to null.
$nameError = $telnoError = $usernameError = $passwordError ="";
$name = $telno = $username = $pass = "";
//Retrieve the field values from registration form.
$name = !empty($_POST ['name']) ? trim($_POST['name']) : null ;
$telno = !empty ($_POST ['telno']) ? trim($_POST['telno']) : null;
$username = !empty($_POST['username']) ? trim($_POST['username']) : null;
$pass = !empty($_POST['password']) ? trim($_POST['password']) : null;
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
$formValid = true; // Boolean - Set to true b4 validating
//If the POST var "register" exists ( the submit button), then I can
//assume that the user has submitted the registration form.
if(isset($_POST['register'])){
//TO ADD: Error checking (username characters, password length, etc).
//Basically, you will need to add your own error checking BEFORE
//the prepared statement is built and executed.
//Now, we need to check if the supplied username already exists.
//Construct the SQL statement and prepare it.
if (empty($_POST["name"])) {
$nameError = "Name is required";
}else {
$name = test_input($_POST["name"]);
// check name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
$nameError = "Only letters and white space allowed";
}
}
if (empty($_POST["telno"])) {
$telnoError = "Tel number is required";
} else {
$telno = test_input($_POST["telno"]);
// check if e-mail address syntax is valid or not
if (!preg_match("/^[a-zA-Z ]*$/",$telno)) {
$telnoError = "Invalid tel no format";
}
}
if (empty($_POST["username"])) {
$usernameError = "username is required";
} else {
$username = test_input($_POST["username"]);
// check name only contains letters and email syntax
if (!preg_match("/^[a-zA-Z ]*$/",$username)) {
$usernameError = "Only letters and email syntax required";
}
}
if (empty($_POST["password"])) {
$passwordError = "passworde is required";
} else {
$pass = test_input($_POST["password"]);
// check name only contains letters and email syntax
if (!preg_match("/^[a-zA-Z ]*$/",$pass)) {
$passwordError = "Only password letter syntax";
}
}
//*******************************************************************
$sql = "SELECT COUNT(username) AS num FROM users WHERE username = :username";
$stmt = $pdo->prepare($sql);
//Bind the provided username to our prepared statement.
$stmt->bindValue(':username', $username);
//Execute.
$stmt->execute();
//Fetch the row.
$row = $stmt->fetch(PDO::FETCH_ASSOC);
//If the provided username already exists - display error.
//TO ADD - Your own method of handling this error. For example purposes,
//I'm just going to kill the script completely, as error handling is outside
//the scope of this tutorial.
if($row['num'] > 0){
die('That username already exists!');
}
//Hash the password as we do NOT want to store our passwords in plain text.
$passwordHash = password_hash($pass, PASSWORD_BCRYPT, array("cost" => 12));
}
//If the signup process is successful.
elseif($formValid){
//******************************ppppp
//Bind our variables.
$stmt->bindValue(':name', $name);
$stmt->bindValue(':telno', $telno);
$stmt->bindValue(':username', $username);
$stmt->bindValue(':password', $passwordHash);
$stmt = $pdo->prepare($sql);
//Prepare our INSERT statement.
//Remember: We are inserting a new row into our users table.
$sql = "INSERT INTO users (name, telno, username, password) VALUES (:name, :telno, :username, :password)";
//Execute the statement and insert the new account.
$result = $stmt->execute();
//What you do here is up to you!
echo 'Thank you for registering with our website.';
}
else {
die('something wrong!');
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Register</title>
<style type="text/css">
.lucida {
font-family: "MS Serif", "New York", serif;
}
body form table {
font-weight: bold;
}
</style>
</head>
<body>
<h1> </h1>
<h1> </h1>
<h1 align="center"> Register</h1>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<div align="center">
<table width="800" border="0">
<tr>
<td width="404" class="lucida"><div align="right">Name :</div></td>
<td width="386"><input class="input" name="name" type="text" value="<?PHP print $name ; ?>">
<span class="error">* <?php echo $nameError;?></span></td>
</tr>
<tr>
<td class="lucida"><div align="right">Contact Number :</div></td>
<td><input class="input" name="telno" type="text" value="<?PHP print $telno ; ?>">
<span class="error">* <?php echo $telnoError;?></span></td>
</tr>
<tr>
<td class="lucida"><div align="right">Email (Username) :</div></td>
<td><input class="input" name="username" type="text" value="<?PHP print $username ; ?>">
<span class="error">* <?php echo $usernameError;?></span></td>
</tr>
<tr>
<td class="lucida"><div align="right">Password :</div></td>
<td><input class="input" name="password" type="text" value="">
<span class="error">* <?php echo $passwordError;?></span></td>
</tr>
<tr>
<td class="lucida"><div align="right"></div></td>
<td> </td>
</tr>
<tr>
<td><div align="right"></div></td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td><div align="right"></div></td>
<td> </td>
</tr>
</table>
<input type="submit" name="register" value="Register">
<br>
</div>
</button>
</form>
</body>
</html>
the form keeps submitting data into the DB even when data is wrong or the field is empty
You are checking $formValid in the wrong place. Your conditions can be summarized as follows:
$formValid = true;
if (isset($_POST['register'])) {
} else if ($formValid) {
} else { ...
As above, if $_POST['register'] is not set (e.g. when loading the registration form) your code will execute whatever is in the second if statement. Your condition structure should be amended to include the form validity check inside the first condition:
$formValid = true;
if (isset($_POST['register'])) {
// validation stuff goes here
if ($formValid) {
//database insert goes here
}
else {
//invalid data. Tell the user
}
}
Also as a rule, you should assume any data from the user is invalid unless proven otherwise i.e. $formValid should be false initially.
Notice: Undefined variable: stmt in C:\xampp\htdocs\eventsite\TMP1kjqc3x.php on line 19
Fatal error: Call to a member function bindValue() on a non-object in C:\xampp\htdocs\eventsite\TMP1kjqc3x.php on line 194
You are trying to use a variable $stmt that has not been defined within the scope of else if($formValid). The same goes for $sql. Any variable must be set before it is used. The order should be:
$sql = "INSERT INTO users (name, telno, username, password) VALUES (:name, :telno, :username, :password)";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':telno', $telno);
$stmt->bindValue(':username', $username);
$stmt->bindValue(':password', $passwordHash);
Try this -
//Prepare our INSERT statement.
//Remember: We are inserting a new row into our users table.
$sql = "INSERT INTO users (name, telno, username, password) VALUES (:name, :telno, :username, :password)";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':telno', $telno);
$stmt->bindValue(':username', $username);
$stmt->bindValue(':password', $passwordHash);
//Execute the statement and insert the new account.
$stmt->execute();
You have bindValue before prepare your statement so you are getting this error. Can prepare your statement below your $sql variable then bind your value. This is working for me.
UPDATED ANSWER
<?php
//register.php
/**
* Start the session.
*/
session_start();
//Include password_compat library.
require 'lib/password.php';
//Include MySQL connection.
require 'connect.php';
//define variables and define to null.
$nameError = $telnoError = $usernameError = $passwordError = "";
$name = $telno = $username = $pass = "";
//Retrieve the field values from registration form.
$name = !empty($_POST ['name']) ? trim($_POST['name']) : null;
$telno = !empty($_POST ['telno']) ? trim($_POST['telno']) : null;
$username = !empty($_POST['username']) ? trim($_POST['username']) : null;
$pass = !empty($_POST['password']) ? trim($_POST['password']) : null;
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
$formValid = true; // Boolean - Set to true b4 validating
//If the POST var "register" exists ( the submit button), then I can
//assume that the user has submitted the registration form.
if (isset($_POST['register'])) {
//TO ADD: Error checking (username characters, password length, etc).
//Basically, you will need to add your own error checking BEFORE
//the prepared statement is built and executed.
//Now, we need to check if the supplied username already exists.
//Construct the SQL statement and prepare it.
if (empty($_POST["name"])) {
$nameError = "Name is required";
$formValid = false;
} else {
$name = test_input($_POST["name"]);
// check name only contains letters and whitespace
if (!preg_match("/^[a-zA-Z ]*$/", $name)) {
$nameError = "Only letters and white space allowed";
$formValid = false;
}
}
if (empty($_POST["telno"])) {
$telnoError = "Tel number is required";
$formValid = false;
} else {
$telno = test_input($_POST["telno"]);
// check if e-mail address syntax is valid or not
if (!preg_match("/^[a-zA-Z ]*$/", $telno)) {
$telnoError = "Invalid tel no format";
$formValid = false;
}
}
if (empty($_POST["username"])) {
$usernameError = "username is required";
$formValid = false;
} else {
$username = test_input($_POST["username"]);
// check name only contains letters and email syntax
if (!preg_match("/^[a-zA-Z ]*$/", $username)) {
$usernameError = "Only letters and email syntax required";
$formValid = false;
}
}
if (empty($_POST["password"])) {
$passwordError = "passworde is required";
$formValid = false;
} else {
$pass = test_input($_POST["password"]);
// check name only contains letters and email syntax
if (!preg_match("/^[a-zA-Z ]*$/", $pass)) {
$passwordError = "Only password letter syntax";
$formValid = false;
}
}
//*******************************************************************
$sql = "SELECT COUNT(username) AS num FROM users WHERE username = :username";
$stmt = $pdo->prepare($sql);
//Bind the provided username to our prepared statement.
$stmt->bindValue(':username', $username);
//Execute.
$stmt->execute();
//Fetch the row.
$row = $stmt->fetch(PDO::FETCH_ASSOC);
//If the provided username already exists - display error.
//TO ADD - Your own method of handling this error. For example purposes,
//I'm just going to kill the script completely, as error handling is outside
//the scope of this tutorial.
if ($row['num'] > 0) {
$usernameError = 'That username already exists!';
$formValid = false;
}
//Hash the password as we do NOT want to store our passwords in plain text.
$passwordHash = password_hash($pass, PASSWORD_BCRYPT, array("cost" => 12));
//$passwordHash = $pass;
if ($formValid) {
//******************************ppppp
//Bind our variables.
//Prepare our INSERT statement.
//Remember: We are inserting a new row into our users table.
$sql = "INSERT INTO users (name, telno, username, password) VALUES (:name, :telno, :username, :password)";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':telno', $telno);
$stmt->bindValue(':username', $username);
$stmt->bindValue(':password', $passwordHash);
//Execute the statement and insert the new account.
$result = $stmt->execute();
//What you do here is up to you!
echo 'Thank you for registering with our website.';
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Register</title>
<style type="text/css">
.lucida {
font-family: "MS Serif", "New York", serif;
}
body form table {
font-weight: bold;
}
</style>
</head>
<body>
<h1> </h1>
<h1> </h1>
<h1 align="center"> Register</h1>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<div align="center">
<table width="800" border="0">
<tr>
<td width="404" class="lucida"><div align="right">Name :</div></td>
<td width="386"><input class="input" name="name" type="text" value="<?PHP print $name; ?>">
<span class="error">* <?php echo $nameError; ?></span></td>
</tr>
<tr>
<td class="lucida"><div align="right">Contact Number :</div></td>
<td><input class="input" name="telno" type="text" value="<?PHP print $telno; ?>">
<span class="error">* <?php echo $telnoError; ?></span></td>
</tr>
<tr>
<td class="lucida"><div align="right">Email (Username) :</div></td>
<td><input class="input" name="username" type="text" value="<?PHP print $username; ?>">
<span class="error">* <?php echo $usernameError; ?></span></td>
</tr>
<tr>
<td class="lucida"><div align="right">Password :</div></td>
<td><input class="input" name="password" type="text" value="">
<span class="error">* <?php echo $passwordError; ?></span></td>
</tr>
<tr>
<td class="lucida"><div align="right"></div></td>
<td> </td>
</tr>
<tr>
<td><div align="right"></div></td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td><div align="right"></div></td>
<td> </td>
</tr>
</table>
<input type="submit" name="register" value="Register">
<br>
</div>
</button>
</form>
</body>
</html>

PHP-Form validation and insertion using MySql

I'm using this code to validate my my html form and I now need to add the form data into a table in mysql. How do I proceed I know the basics of creating a connection and sql databases but since I've already used the form's submit button i don't know how to get the data to a place where I can insert it again
<?php
// define variables and initialize with empty values
$nameErr = $passErr = $emailErr =$cpassErr="";
$name = $pass = $cpass = $email = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["username"])) {
$nameErr = "Enter Username";
}
else {
$name = $_POST["username"];
}
if (empty($_POST["password"])) {
$passErr = "Enter password";
}
else {
$pass = $_POST["password"];
}
if (empty($_POST["cpassword"])) {
$cpassErr = "Retype password";
}
else {
$cpass= $_POST["cpassword"];
}
if (empty($_POST["email"])) {
$emailErr = "Enter email";
}
else {
$email = $_POST["email"];
}
}
?>
<html>
<head>
<style>
.error {
color: #FF0000;
}
</style>
</head>
<body>
<form method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<table border="0" cellspacing="20">
<tbody>
<tr>
<td>Username:</td>
<td><input type="text" name="username" accept="" value="<?php echo htmlspecialchars($name);?>">
<span class="error"><?php echo $nameErr;?></span>
</td>
</tr>
<tr>
<td>Password:</td>
<td><input type="text" name="password" accept="" value="<?php echo htmlspecialchars($pass);?>">
<span class="error"><?php echo $passErr;?></span></td>
</tr>
<tr>
<td>Confirm Password:</td>
<td><input type="text" name="cpassword" accept=""value="<?php echo htmlspecialchars($cpass);?>">
<span class="error"><?php echo $cpassErr;?></span></td>
</tr>
<tr>
<td>Email:</td>
<td><input type="text" name="email" accept="" value="<?php echo htmlspecialchars($email);?>">
<span class="error"><?php echo $emailErr;?></span></td></td>
</tr>
</tbody>
</table>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
Code for the connection
<?php
$host="localhost";
$username="root";
$password="root";
$db_name="LSDB";
$con=mysqli_connect("$host","$username","$password","$db_name");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
var_dump($_POST);
$u=$_POST['username'];
$p=$_POST['password'];
$e=$_POST['email'];
$ph=$_POST['phone'];
$sql="INSERT INTO register (username,password,email,phone)
VALUES
('$u','$p','$e','$ph')";
if (!mysqli_query($con,$sql))
{
die('Error: ' . mysqli_error($con));
}
mysqli_close($con);
?>
first off i would suggest you escaping the inputs.
also worth noting you could use prepared statements and object oriented way of mysqli as most of the documents on OO are clearer than the procedural way.
like :
<?php
$u=striptags($_POST['username']);
$p=striptags($_POST['password']);
$e=filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
$ph=(int)$_POST['phone'];
$mysqli = new mysqli($host,$username,$password,$db_name);
$query = "INSERT INTO register (username,password,email,phone) VALUES (?,?,?,?)";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("sssi", $u, $p, $e, $ph);
$stmt->execute();
$mysqli->close();
?>
it would not also hurt using hash on your password like :
<?php
$salt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
$passh = crypt($pass, '$6$'.$salt);
?>
do note that you will need to store the salt in mysql also so you can compare it later
so with these your passwords are safer and if your database gets stolen the passwords will remain hashed.
When the user submits the form, if the validation was successful, then you should execute a process function, where you can place as much instructions as you need, including storing the data in a database, or printing it in an auto-generated webpage. Everything you need.
In another order of things, looks like that code of you is too simple and hence vulnerable to cross-site scripting. You should not only validate if the fields are empty or not, but also you should use some regular expressions and the function preg_match( ) to filter which characters are entered. The best protection is to allow the user enter only the characters that are needed in each field, and not any others than those.
Example on how to handle the logic of the form:
if ($_POST['_submit_check']) {
// If validate_form() returns errors, pass them to show_form()
if ($form_errors = validate_form()) {
show_form($form_errors);
} else {
// The data sent is valid, hence process it...
process_form();
}
} else {
// The form has not been sent, hence show it again...
show_form();
}

How to check value in mysql with php pdo connection?

I'm a totally beginner in php, so I need help with my registration script. I have 4 fields, 1 username (which is in the back transformed in an email address), 1 current email address of owner and 2 password fields. Registration is working, I only want to add the validation of username in case exists or not. My problem is that I don't know where and how to do it, should I create a function? How? I wanted to keep it simple so I didn't create any kind of session, is it possible without, as is?
here is the code:
<?php
$host = '127.0.0.1';
$dbuser = 'reguser';
$dbpass = 'regpass';
$dbn = 'regform';
$conn = new PDO("mysql:host=$host;dbname=$dbn", $dbuser, $dbpass);
$RegScrIdErr = $RegScrIdChrErr = $OwnAddressErr = $Password1Err = $Password2Err = $PasswordMErr = "";
$formValid = true;
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["RegScrId"])) {$RegScrIdErr = "Userame is required"; $formValid = false;}
else {$RegScrId = check_input($_POST["RegScrId"]);
if (!preg_match("/^[a-zA-Z0-9]*$/",$RegScrId)){$RegScrIdErr = "Only letters and numbers allowed"; $formValid = false;}
}
if (empty($_POST["OwnAddress"])) {$OwnAddressErr = "Email is required"; $formValid = false;}
else {$OwnAddress = check_input($_POST["OwnAddress"]);
if (!preg_match("/([\w\-]+\#[\w\-]+\.[\w\-]+)/",$OwnAddress)){$OwnAddressErr = "Invalid email format"; $formValid = false;}
}
if (empty($_POST["Password1"])) {$Password1Err = "Password field can't be empty!"; $formValid = false;}
else {$Password1 = check_input($_POST["Password1"]);}
if (empty($_POST["Password2"])){$Password2Err = "Password Confirmation can't be empty!"; $formValid = false;}
else {$Password2 = check_input($_POST["Password2"]);
if ($_POST["Password1"]!= $_POST["Password2"]) {$PasswordMErr = "Password does not match!"; $formValid = false;}
}
if ($formValid) { header('Location: index.html'); }
}
function check_input($data){
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
$RegScrIdFull = "$RegScrId#RegScrserver.com";
$userIp = $_SERVER['REMOTE_ADDR'];
$hash = hash('sha1', $Password1);
FUNCTION createSalt(){
$text = md5(uniqid(rand(), TRUE));
RETURN substr($text, 0, 3);
}
$salt = createSalt();
$PasswordSec = hash('sha256', $salt . $hash);
if ($formValid) {
$qry = $conn->PREPARE('INSERT INTO userlist (RegScrId, password, email, userIp, salt) VALUES (?, ?, ?, ?, ?)');
$qry->EXECUTE(array($RegScrIdFull, $hash, $OwnAddress, $userIp, $salt));
$conn = null;
}
?>
<div id="wrapper">
<header><img src="img/logo3.png" width="170" height="110" /><br><br>
</header><br>
<div id="section_contact">
<form name="register" method="post" action="<?php echo $_SERVER["PHP_SELF"];?>"><br />
<table width="850" border="0" id="tb-form">
<tr>
<td class="tb-form-left" colspan="2"><h4><strong>Sign Up</strong></h4><br /></td>
</tr>
<tr>
<td class="tb-form-left"><input type="text" name="OwnAddress" maxlength="30" placeholder=" Own Email Address" value="<?php echo $ $OwnAddress;?>" /><span class="error"><?php echo $OwnAddressErr;?></span></td>
</tr>
<tr>
<td class="tb-form-left"><input type="text" class="RegScrIdPic" maxlength="28" name="RegScrId" id="email" placeholder=" RegScrserver Username" value="<?php echo $RegScrId;?>" /><span class="error"><?php echo $RegScrIdErr;?><?php echo $RegScrIdChrErr;?></span></td>
</tr>
<tr>
<td class="tb-form-left"><input type="password" name="Password1" placeholder=" Enter Password"/><span class="error"><?php echo $Password1Err;?></span></td>
</tr>
<tr>
<td class="tb-form-left"><input type="password" name="Password2" placeholder=" Confirm Password" /><span class="error"><?php echo $Password2Err;?><?php echo $PasswordMErr;?></span></td>
</tr>
<tr>
<td class="tb-form-left"><input id="form-btn" type="submit" value="Create Account" /></td>
</tr>
</table>
</form>
</div>
</div>
</div>
</body>
</html>
if you want implements validation when username exist in your database you first should ask database if username really exists. Before your insert you should use SELECT query
$sth = $conn->prepare('SELECT id FROM users WHERE username=:username');
$sth->bindValue(':username',$username,PDO::PARAM_STR);
sth->execute();
while($row = $sth->fetch()){
/// ....... here you get username
}
// if in $row you get username you can use now validation for example
if(!empty($row)){
my_validation_function();
}
else{
// we dont want approaching form so we redirect customer to some page
header('location: some url');
}
if ($formValid) {
$qry = $conn->PREPARE('INSERT INTO userlist (RegScrId, password, email, userIp, salt) VALUES (?, ?, ?, ?, ?)');
$qry->EXECUTE(array($RegScrIdFull, $hash, $OwnAddress, $userIp, $salt));
$conn = null;
}

Categories