Less-Insecure Password Site

First, I am sorry my code is VERY LONG, but my professor wants it all on one page instead of in separate pages and the requirements are lengthy. Also, this is for practice and not a real username and password site. I am required to use salting instead of the password hashing function as well.

The issues that I am running into right now (might have others after I can figure these ones out and test some more. I have been writing this code for days now and am beyond confused since I thought I had it figured out. :frowning:

  1. When the link is clicked to create a new account, the URL is updating with the GET variables but the code is not running to change the form displayed on the same page to the new account info instead of the login info. I am trying to trigger this change via the GET with the $show and $new variables.

  2. I am getting this error when I try to add in a username and password (and click submit) which is why I am guessing it is not connecting to the database as well. the line it refers to is $stmt = mysqli_stmt_init($conn);.

Fatal error : Uncaught TypeError: mysqli_stmt_init(): Argument #1 ($mysql) must be of type mysqli, string given in C:\xampp\public_html\csis2440\less-insecure\index.php:302 Stack trace: #0 C:\xampp\public_html\csis2440\less-insecure\index.php(302): mysqli_stmt_init(’’) #1 C:\xampp\public_html\csis2440\less-insecure\index.php(377): usernameExists(’’, ‘werwe’) #2 C:\xampp\public_html\csis2440\less-insecure\index.php(31): loginUser(’’, ‘werwe’, ‘werwe’) #3 {main} thrown in C:\xampp\public_html\csis2440\less-insecure\index.php on line 302

More questions may follow once I can actually test the code upon moving past these errors. Thank you for your help.

End Goal: (seems to be easier than I have made it but I am new and alas make things difficult on myself)

  • Process all information on the same page.

  • A login form is displayed, if a user enters their login info then it looks to the database to see if they have an account. If so then “access is granted” and the form is not displayed anymore. If not, then “access denied” and the form shows with the error message that is applicable.

  • If the user clicks on the New Account link, then another form is shown instead (looks the same but the header should be different). If filled out the username and password are inserted into the database. If the username already exists and an error is displayed.

My database includes: a table called user_info and it contains 3 rows: id (auto incremented), username, password.

<?php	
	session_start();

	//VARIABLES
	$userError = $passError = $msg = $username = $password = $welcome= $welcomes = $conn = ""; 
	$show = true;
	$new = false;

	//ARRAY
	$welcome = array("Hola","Aloha","Bonjour","Hallo","Ciao","Konnichiwa",);


	if(isset($_GET['show']))
	{
		$show=true;
	}
	
	if(isset($_GET['new']))
	{
		$new=true;
	}
	

	if($_SERVER['REQUEST_METHOD'] == 'POST')
	{
		//GET THE POST VARIABLES
		$username = $_POST['username'];
		$password = $_POST['password'];

		//USERNAME AND PASSWORD ENTERED AND SUBMIT BUTTON CLICKED
		if(isset($_POST["submit"]))
		{
			dbconn();
			
			if(emptyInputLogin($username, $password) !== false)
			{
				header("location: index.php?error=emptyinput");
				$msg = 'Access Denied';
				$show = true;
				$new = false;
				exit();
			}
			else
			{
				loginUser($conn, $username, $password);		
				header("location: index.php?");
				$msg = 'Access Granted';
				$show=false;
				$new = false;
				exit();
			}
		}

		//SIGN UP SUBMIT BUTTON CLICKED
		elseif (isset($_POST['newsubmit'])) 
		{
			dbconn();
			
			if(emptyInputSignup($username, $password) !== false)
			{
				header("location: index.php?error=emptyinput");
				$show = false;
				$new = true;
				exit();
			}
			if(invalidUsername($username) !== false)
			{
				header("location: index.php?error=invalidusername");
				$show = false;
				$new = true;
				exit();
			}
			if(usernameExists($conn, $username) !== false)
			{
				header("location: index.php?error=usernametaken");
				$show = false;
				$new = true;
				exit();
			}
			
			createUser($conn, $username, $password);
		}

		//IF CLEAR HAS BEEN CLICKED
		elseif(isset($_POST['reset']))
		{
			$username = "";
			$password = "";
		}
		
		//LOG OUT BUTTON CLICKED
		elseif (isset($_POST['out'])) 
		{
			logout();
			$show = true;
			$new = false;
		}

		//SIGNUP BUTTON CLICKED
		elseif(isset($_POST['create']))
		{
			$show = false;
			$new = true;
		}

		//ALREADY HAVE ACCOUNT BUTTON CLICKED
		elseif(isset($_POST['already']))
		{
			$show = true;
			$new = false;
		}

		else
		{
			header("location: index.php?");
			$show = true;
			$new = false;
		}
	}
?>


<!DOCTYPE html>
	<html>
		<head>
			<link type="text/css" rel="stylesheet" href="css\style.css">
			<script src="js\script.js" defer></script>
			<title>Less Insecure</title>
		</head>

		<body>
			<nav>
				<div class="wrapper">
					<ul>
						<?php
							if(isset($_SESSION["username"]))
							{
								echo '<button type="submit" name="out" id="logout" class="button"value="Log Out">Log Out</button>';
							}
						?>
					</ul>
				</div>
			</nav>

			<?php
				//NO ERRORS AVAILABLE AND THE BUTTON HAS BEEN PUSHED
				//ACCESS GRANTED
				if (!$show && !$new)
				#if(isset($_SESSION["username"]))
				{
					echo '<div class="output">
						<h1 class = "success">'.$msg.'</h1><br>
					<	div>
							<h2 class = "welcomemsg">'; 
								echo $welcome[mt_rand(0, count($welcome)-1)];
								echo ', '.$_SESSION["username"].' !<h2>
						</div>
					</div>';
				}

				//LOGIN FORM
				elseif ($show)
				{
					echo '
						<section class="form-content"> 
							<!--DENIED MESSAGE-->
							<div>
								<h2 class = "denied">'.$msg.'</h2>
							</div>
							<h2>Log In</h2>
							<br>
							<form method="post" action="">
								<p>
									<label>Username </label>
									<input type="text" name="username" placeholder="Username">
								</p>
								<p>
									<label>Password</label>
									<input type="password" name="password" placeholder="Password">
								</p>
								<p>
									<button type="submit" name="submit" id="submit" class="button" value="Submit">Log In</button>
									<button type="reset" name="reset" id="reset" class="button" value="Clear">Clear</button>
									<div>
										<span>Don\'t have an account? <button type="submit" name="create" id ="submit" class="button" value ="New">SignUp</abutton></span>
									</div>
								</p>
							</form>
							<div class="errors">';

							//DISPLAY LOG IN ERROR IF AVAILABLE
							if(isset($_GET["error"]))
							{
								if($_GET["error"] == "emptyinput")
								{
									echo "<h2>Access Denied</h2><p>Please fill in all fields.</p>";
								}
								elseif($_GET["error"] == "wronglogin")
								{
									echo "<h2>Access Denied</h2><p>Oops, it looks like that was incorrect. Try again.</p>";
								}
								elseif($_GET["error"] == "stmtfailed")
								{
									echo "<h2>Access Denied</h2><p>Sorry, something went wrong.</p>";
								}
							}
						
						'</div>
						</section>';
				}

				//SIGN-UP FORM
				elseif ($new)  
				{
					echo '
						<section> 
							<h2> New Account </h2>
							<div class="newaccount">
								<form  action="" method="post">
									<p>
										<label>Username </label>
										<input type="text" name="username" placeholder="Username">
									</p>
									<p>
										<label>Password</label>
										<input type="password" name="password" placeholder="Password">
									</p>
									<p>
										<button type="submit" name="submit" id="newsubmit" class="button" value="Submit">Sign Up</button>
										<button type="reset" name="reset" id="reset" class="button" value="Clear">Clear</button>
										<div>
											<span>Already have an account? <button type="submit" name="already" id ="submit" class="button" value ="New">Log In</abutton></span>
										</div>
									</p>
								</form>
							</div>
							<div class="errors">';

							//DISPLAY SIGN UP ERROR IF AVAILABLE
							if(isset($_GET["error"]))
							{
								if($_GET["error"] == "emptyinput")
								{
									echo "<p>Please fill in all fields.</p>";
								}
								elseif($_GET["error"] == "invalidUid")
								{
									echo "<p>Choose a valid username consisting of numbers and letters only.</p>";
								}
								elseif($_GET["error"] == "passwordsdontmatch")
								{
									echo "</h2><p>Passwords don't match.</p>";
								}
								elseif($_GET["error"] == "stmtfailed")
								{
									echo "<p>Sorry, something went wrong, try again.</p>";
								}
								elseif($_GET["error"] == "usernametaken")
								{
									echo "<p>Username already taken, please try a different one.</p>";
								}
								elseif($_GET["error"] == "none")
								{
									echo "<p>Congratulations, you have been signed up!</p>";
								}
							}
							'</div>
						</section>';
				}
			?>
		</body>
	</html>



<?php
	//FUNCTIONS

	//DATABASE CONNECTION INFO
	function dbconn()
	{
		if ($_SERVER['HTTP_HOST'] == 'localhost') //LOCAL
		{
			define('HOST', 'localhost');
			define('USER', 'root');
			define('PASS', '1550');
			define('DB', 'pass_system');
		}
		else //REMOTE
		{
			define('HOST', 'localhost');
			define('USER', 'mountmer_root');
			define('PASS', 'otraIcjwtgbotra');
			define('DB', 'mountmer_pass_system');
		}
		
		//CONNECT TO DATABASE
		#$conn = mysqli_connect(HOST, USER, PASS, DB);
		$conn = new mysqli(HOST, USER, PASS, DB);

		if(!$conn)
		{
			die("Connection failed: " . mysqli_connect_error());
		}
	}
	

	function emptyInputSignup($username, $password)
	{
		$result;
		if (empty($username) || empty($password))
		{
			$result = true;
		}
		else
		{
			$result = false;
		}
		return $result;
	}


	function invalidUsername($username) 
	{
		$result;
		if (!preg_match("/^[a-zA-Z0-9]*$/", $username))
		{
			$result = true;
		}
		else
		{
			$result = false;
		}
		return $result;
	}


	function usernameExists($conn, $username)
	{
		$sqli = "SELECT * FROM user_info WHERE username = ?;";
		$stmt = mysqli_stmt_init($conn);
		
		if(!mysqli_stmt_prepare($stmt, $sqli))
		{
			header("location: index.php?error=stmtfailed");
			$show = true;
			$new = false;
			#exit();
		}
		mysqli_stmt_bind_param($stmt, "s", $username);
		mysqli_stmt_execute($stmt);
		
		$resultData = mysqli_stmt_get_result($stmt);
		
		if($row = mysqli_fetch_assoc($resultData))
		{
			return $row;
		}
		else
		{
			$result = false;
			return $result;
		}
		mysqli_stmt_close($stmt);
	}


	function hashit($password)
	{
		$salt1 = 'knridkfva234lke269jg90fnbsdifad23435fvnzmvpedfnk67u5th43rn98bseirvm';
		$salt2 = 'zmdkowpqkdjruwqwpir4dbmer093fekrgh9342ojqepfoiewrvneon498w4'; 
		$password = $salt1.$password.$salt2;
		$hashedPwd = hash('sha512', $password);

		return $hashedPwd;
	}


	function createUser($conn, $username,$password)
	{
		$sqli = "INSERT INTO user_info (username, password) VALUES (?, ?);";
		$stmt = mysqli_stmt_init($conn);
		
		if(!mysqli_stmt_prepare($stmt, $sqli))
		{
			header("location: index.php?error=stmtfailed");
			$show = true;
			$new = false;
			exit();
		}

		hashit();
		
		mysqli_stmt_bind_param($stmt, "ss", $username, $hashedPwd);
		mysqli_stmt_execute($stmt);
		mysqli_stmt_close($stmt);
		
		header("location: index.php?error=none");
			$show = false;
			$new = false;
			exit();
	}


	function emptyInputLogIn($username, $password)
	{
		$result;
		if (empty($username) || empty($password))
		{
			$result = true;
		}
		else
		{
			$result = false;
		}
		return $result;
	}


	function loginUser($conn, $username, $password)
	{
		$usernameExists = usernameExists($conn, $username);
		
		if($usernameExists === false)
		{
			header("location: index.php?error=wronglogin");
			$show = true;
			$new = false;
			exit();
		}
		
		$pwdHashed = $usernameExists["password"];
		$checkPwd = password_verify($password, $pwdHashed);
		
		if($checkPwd === false)
		{
			header("location: index.php?error=wronglogin");
			$show = true;
			$new = false;
			exit();
		}
		elseif ($checkPwd === true)
		{
			session_start();
			$_SESSION["id"] = $usernameExists["id"]; 
			$_SESSION["username"] = $usernameExists["usersname"]; 
			header("location: index.php?");
			$show = false;
			$new = false;
			exit();
		}
		
	}

	function logout()
	{
		session_start();
		session_unset();
		session_destroy();
		
		header("location: index.php?");
		$show = true;
		$new = false;
		$_GET['error']="";
		exit();
	}

?>


You professor sounds like an idiot as he or she is having you basically waste you time writing a password security function that can be resolved with PHP’s built-in security functions. I am sure someone here will help you, but to me it’s an act of futility.

2 Likes

I hope someone can help. I have scrambled my brain trying to learn this and I think I get more confused with it all on one page instead of broken out and a little clearer.

@Strider64 is right, your “professor” needs to go back to school. You are wasting your time. You would NEVER do what he is asking of you. He should be teaching you PDO anyways.

1 Like

Yeah he also said in the instructions that we specifically can NOT use PDO as well. I am not sure on his reasoning for these, but non-the less I am stuck on this assignment. I had originally used the PHP hash function but then found in the rubric that we can’t so back to square one I went.

Is there someone that can help me solve the issues that I am having with connecting to the database and showing the correct form or not? I feel that what we are being asked is all of the hard ways to go about it, but in the end maybe it will help us appreciate the easier ways to do things when we get in another class and we learn more about those. I dunno.

Could you post the actual specs as they were given to you?

@benanamen Sure. It’s a two-part assignment which I was trying to incorporate what I could in this submission to have less to add/alter for the next submission.

PART-ONE (I was trying to incorporate some of part two as well to make it less work).

  1. Create the following folder structure in your htdocs folder on your computer:
  • less-insecure
    • js
    • img
    • css
    • includes
  1. Create a database with at least one table with at least the following fields:
  • ID
  • username
  • password
  1. Note: Make sure that you have existing users in your database that you can test to make sure they are able to log in if they have the right credentials or not if they are wrong.
  2. Create the following file(s) on your computer in the *less-*insecure folder:
  • index.php
  1. In the index.php file:
  2. Create a standard web page with all the basics (doctype, html tag, head tag, body, etc.)
  3. In the body of the page, create a web form that asks for the user username and password.
    * be sure to include a reset button
    * be sure to include a submit button
    * when submitted, it will compare the username and password to all of the records in the table and one of two things will happen:
    • If they enter the correct user/password (one of the ones from the text file) the page will say “access granted” and will have no other content.
    • If they enter the wrong credentials the form will display with a message above it that says “access denied”
    • See sample screen shots below
  4. Give the site some personality using CSS.
  5. Think about design and layout
  6. Be sure to do all of your styling in a CSS file that is linked to your index.php file
  7. Test the site:
  • Make sure that you test is with all of the correct credentials from the text file
  • Test it with correct users, but wrong passwords
  • Test it with wrong users, but correct passwords
  • Test is with wrong users and wrong passwords
  • Make sure that you CSS works correctly
  1. Upload the site:
  • Once the site has been tested, upload the less-insecure directory to your server in the htdocs on your server.
  • Test the site again once it’s uploaded and live
  1. Notes:
  • All of the php and html code will be in the index.php file.
  • When the form is processed, it will reload the index.php displaying different content depending on the results of the form input.

Helpful Hints

Below are a few hints that may help you along your journey

  • Remember the 5 basics steps of interacting with the DB:
    1. Create constants for use in the connection function
    2. Connect with the mysqli_connect() function
    3. Write an SQL query/command
    4. Pass the query to the DB via the connection made in step 2
    5. Loop through the results if necessary

Sample Images

Note: the images below have no style applied to them. I expect your sites to be styled and to look professional.

Default Display of index.php

Default Image

Access Denied Display of index.php

Access Denied Image

Access Granted Display of index.php

Access Granted Image

Additional Content

Implement (at two) three of the following: I was trying to do #1 and #3)

  1. Allow someone the ability to create a username and password
  2. Once the user logs in, display a note that says, you have logged in “x” number of times (x being the actual number of logins)
  • Hint: You’ll need to add a field in the database to track this.
  1. Have a custom “welcome” message display that is different for each user
  2. If the same user tries to log in with the wrong password 3 times in a row, change their password and display a message stating that their account is locked.

PART 2: (separate submission)
You will copy the existing (“less-insecure”) project and paste it into a NEW folder called “more-secure”. Modify the newly copied version as described below:

  1. Create a link called “users”
  • When clicking on “users” it shows the username and password for all users as they are stored in the database
  • Note, in the real world, this is foolish and an obvious security risk. However, for grading purposes (and sense this is not a real site), I need it to be present
  1. Add a new button/link to the form called “create account”
  2. When the user clicks on the button a new page will load called “create-account.php” which will have the following:
  • User Name Field
  • Password Field
  • Verify Password Field
  • Secret Code Field
  • Submit Button called “Create Account”
  • Reset Button
  • Link to the Log In page.
  1. Verify that the “password” and “verify password” fields match each other or an error message must be shown
  • Be sure to display an appropriate error message on the page if needed
  • Be sure to keep all of the rest of the entered data in the fields.
  • Until these two fields match, they will not be able to create an account
  1. They must enter a secret code that needs to match the secret code that is stored in your database (you’ll probably need a new table for the secret code)
  • The secret code is “rawhide”
  1. Your PHP code will need to do several things:
  • Make sure the newly entered user name is not already in the database
  • Make sure they got the secret code correct
  • If the user doesn’t exist, and the got the “secret” code correct, insert the new username and password, and be sure to salt and hash the password.
  • Note do NOT use the PHP function password_hash().
  • Display a message stating that the user was created
  1. The two password fields and “secret code” field must not show the values entered by the user (it should show dots instead)
  2. Once the user creates an account they will be able to log in to the system using the newly created account
  3. Display all content in the DOM (i.e., not in JS alert() boxes)
  4. Be sure that the original users (i.e., dana, fox, beavis, butthead) can still log in
  • Hint: you’ll have to modify things to make sure that their passwords are hashed
  1. Style the site (all pages)
  • Think about font sizes, colors, styles, etc.
  • Think about the user experience
  • Think about padding, and margin
  • The site needs to look “clean” not cluttered
  • It needs to be a pleasant user experiences
  • Error messages and other text need to be easy to read, and noticeable rather than placed “randomly”
  • Be thoughtful about the user’s experience.
  1. Final Note:
  • Do NOT use PDO. Using PDO will result in 0 points for the assignment.
  • If you don’t know what PDO is then you definitely won’t accidentally use it. :slight_smile:

I think another confusing part for me putting these together is he teaches us in the lectures how to make a site using different pages in addition to the index page, but then the assignments are only on one page which make my eyes go cross trying to figure the layout right and get everything to work properly.

I updated my code that is posted.

I figured out how to get the form to update to the login page to the signup page, but I am still having the issue with the error and getting it to connect to the database. I am also having an issue getting the 'error=(some value here)" to clear out of the URL if the clear button or sign up/login buttons are selected.

Did this programming class suggest/require user written functions? If so, it neglected to teach proper function design, including local variable scope. Php uses a (proper) black-box model for functions. Variables created inside of a function have local variable scope and don’t exist outside of the function. You need to return the result that a function produces so that it can be used (assigned/tested) by the calling code. This allows you to easily write function code without needing to know/check if any variables you are using are already being used in the main program, an important feature when writing large applications or when dealing with teams of programmers working on a project. Your dbconn() function needs to return the connection to the calling code, so that it can assign it to a main program variable that can be used through the rest of the code. BTW - you should have one call to dbconn(), near the start of your code.

The reason you are getting a non-helpful php error about the connection variable being a string (the main/first error should have been about an undefined $conn variable, that would have pointed you in the correct direction of finding the cause of the problem) is because of the long list of variables you are creating and assigning an empty string to. Don’t do this at all and certainly not for a variable that your code is creating internally, such as the variable holding the database connection.

Well this assignment is making me feel uneasy about this course. Yes, this is how my teacher has been teaching us to do functions and has been telling us to declare variables at the top so they are more of a global variable. He said that is the easy way to take care of some of the errors that we had pop-up in class during his lecture.

Between functions, variables, salting instead of php hashing function, and not using PDO I am not to confident that I will undersand this two part assignment to pass the class let alone the final project. UG.
Is there a good website/book or some kind of reference for me to look at to learn these correctly? I am not sure what I can do for this assignment since he won’t allow certain things that others have said should be done and the way I am being tough is pointless and a waste of time, but I want to pass this class and maybe do a reteaching over December so I am prepared for my next programing class.

What might help you is to start with separate files and include them. Once you get everything working, then replace the include call with the file contents. It will keep your logic page much cleaner while you are working on it.

2 Likes

Ouch… Professor is obviously inept and I have the qualifications to say that.

Where are you still having difficulty?

1 Like

@astonecipher I have been trying to separate my code into pages to then put it back together again as suggested but I think I am making more of a mess out of it at this point. Given my updated code above, I am stuck with the database connection mainly. The smaller issue is that I am not getting the correct error to post every time or go away if the user goes to the create account page from the login page after trying and failing or vice versa.

I also tried watching some of his videos on youtube again to see if I missed anything in my notes and I don’t see that I did. The difficulty besides the outdated teaching seems to be that he teaches in many pages and goes back and forth between this and that each time, but then our assignments which we have only had a few, are all on one page and don’t really relate to the best to the assignment. I told him this and he said he would think about improving it with other videos in the future but nothing he can do about it now. Besides this two-part assignment, I have a final that I feel I am very unprepared to accomplish. Let’s just say my hair is falling out and I can’t sleep. I have watched so many videos and can’t get my head around the way he wants us to complete this assignment vs the way that everyone else is completing this same work.

Links? I would like to see what he is putting out there. I hope he hasn’t turned commenting off. I will probably have a few choice comments to leave.

Here is the one about hashing/encryption. I am sure you can find all the others off of this one. https://youtu.be/oQLbhZTe2XM

Before this one it was all about a palindrome website that make it very hard to understand our assignments since it was so different.

He tells us in the syllabus that he doesn’t give us all the info we need as well for the assignment because he wants us to search and find stuff on our own but given talking with you all I am feeling that is not helping my situation as I am mixing stuff I probably shouldn’t be.

I watched the video. There are a handful of issues with what he has shown. What is interesting is he has videos on OOP that are OK so he does know more advanced coding.

You might want to talk to him privately and tell him programming experts have said there are issues with what he is teaching.

@benanamen Well that’s very disappointing given that I am paying for a class and degree that I expect to give me the latest and most up to date information. I mean we aren’t starting to make wheels out of stone before learning how to make them from rubber. I will try to talk to him, but given my last convo on how I am lost trying to relate his lectures to the assignments and how nothing is going to be done now but maybe sometime in the future, I don’t have much hope.

Nothing says you have to stick to the path of the professor. Venture on you own on the side and learn the right way. Here is a tutorial on PDO that will do very well for you and it is free. Learn this and you will be on the right path.

I would also suggest you start a pet project to learn on. Perhaps an Address Book. It can start very simple using a text file for data and be refactored all the way up to more advanced with a database and multiple users.

If you are on Windows, set up a local Dev with Laragon
https://laragon.org/

* Other topics you will want to learn about is Database Normalization, Seperation of Concerns, Guard Clauses and Cyclomatic Complexity.

2 Likes
Sponsor our Newsletter | Privacy Policy | Terms of Service