patternphpMinor
PHP registration/login form
Viewed 0 times
phploginregistrationform
Problem
I'm fairly new to MySQLi and PHP, but I've been working at it for a bit now, and reading up on how to make secure login forms, avoid SQL injection etc. I'm a mere amateur though.
I've created an index.html page (not including the code here, just a basic form though), a register.html page (not including the code here, again it's just a basic form), adduser.php (which gets its call from "action" on the registration form),login.php (obviously gets its "action" from the index.html login form), logout.php, and a restricted.php with a check if session is active.
Everything is working. I'm just looking for some expert eyes to take a gander at my code and let me know if I'm missing anything whether it be major or minor, any security flaws, etc. Currently I don't have any form validation as I'm thinking of doing it client side with jQuery.
adduser.php
login.php
```
connect_errno > 0) {
die('Unable to connect t
I've created an index.html page (not including the code here, just a basic form though), a register.html page (not including the code here, again it's just a basic form), adduser.php (which gets its call from "action" on the registration form),login.php (obviously gets its "action" from the index.html login form), logout.php, and a restricted.php with a check if session is active.
Everything is working. I'm just looking for some expert eyes to take a gander at my code and let me know if I'm missing anything whether it be major or minor, any security flaws, etc. Currently I don't have any form validation as I'm thinking of doing it client side with jQuery.
adduser.php
connect_errno > 0) {
die('Unable to connect to database [' . $mysqli->connect_error . ']');
}
if(isset($_POST['submit'])) {
$errors = array();
$data = array();
$fname = $_POST['fname'];
$lname = $_POST['lname'];
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$confpass = $_POST['confpass'];
$password_hash = password_hash($password, PASSWORD_DEFAULT);
if(!($stmt = $mysqli->prepare("INSERT INTO users (fname, lname, username, email, password)
VALUES (?,?,?,?,?)"))){
echo "Prepare failed: (" . $mysqli->errno . ")" . $mysqli->error;
}
if(!$stmt->bind_param('sssss', $fname, $lname, $username, $email, $password_hash)){
echo "Binding paramaters failed:(" . $stmt->errno . ")" . $stmt->error;
}
if(!$stmt->execute()){
echo "Execute failed: (" . $stmt->errno .")" . $stmt->error;
}
if($stmt) {
header('Location: index.html#testform')
}
else{
echo "Registration failed";
}
}
$mysqli->close();login.php
```
connect_errno > 0) {
die('Unable to connect t
Solution
Security
First of, your code looks pretty good, especially from a security point of view. You use prepared statements, and you use them correctly, and you use bcrypt instead of some weaker hashing algorithm such as md5 or sha.
There are a couple of things which might cause problems under certain conditions, and as defense in depth it might be a good idea to include them:
Misc
First of, your code looks pretty good, especially from a security point of view. You use prepared statements, and you use them correctly, and you use bcrypt instead of some weaker hashing algorithm such as md5 or sha.
There are a couple of things which might cause problems under certain conditions, and as defense in depth it might be a good idea to include them:
- always
dieafter a redirect, because the redirect does not necessarily stop execution of the PHP script (you can easily test this yourself:header('Location: index.html'); echo "secret";using curl:curl localhost/redirect.phpwould give yousecret, because curl doesn't follow redirects by default).
- you have
new mysqli ([credentials])in at least two places. This is not only bad because duplication makes code harder to read and maintain, with credentials it is especially bad because it makes it harder to remember to hide them (when posting code somewhere else, submitting it in version control, etc). It also makes it harder to move those PHP files that do contain credentials outside the web root. Just put the database connection in one file (located outside the web root) and wrap it in agetConnectionfunction (this also makes it possible to use the same database connection for all queries, which improves performance).
- with current default PHP.ini settings, this is less important, but it is still always a good idea to regenerate the session id when the state of the session changes (eg when logging in) to prevent session fixation.
- as @sjonniesjon said, don't echo actual error messages to the user. It can directly enable some attacks such SQL injections into some keywords (such as insert, update, order by, etc) which only display data in error messages, and it can help an attacker identify vulnerabilities.
Misc
- your indentation is sometimes off, leading to harder to read code. Your brackets are also placed inconsistently.
- you also have too many newlines in some places.
Context
StackExchange Code Review Q#78469, answer score: 3
Revisions (0)
No revisions yet.