0

After my last code was vulnerable to sql injections, I tried to change it so much and make it as invulnerable as I understand it, but I'm not so sure I did a great job. So I made the following code for registering users and for logging them in, is this sql injection proof? I'm very scared about attacks.

<?php
session_start();

// initializing variables
$username = "";
$email    = "";
$errors = array(); 
$check = isset($_POST['cbsu']) ? "checked" : "unchecked";

$db = mysqli_connect('', '', '', ''); //has real values in the actual file

if (isset($_POST['reg_user'])) {

  $username = $_POST['username'];
  $email = $_POST['email'];
  $password_1 = $_POST['password_1'];
  $password_2 = $_POST['password_2'];

  if (empty($username)) { array_push($errors, "Username is required.");}
  if (!preg_match("/^[a-zA-Z0-9]*$/", $username)){ array_push($errors, "Invalid username."); }
  if (empty($email)) { array_push($errors, "Email is required");}
  if (!filter_var($email, FILTER_VALIDATE_EMAIL)){
      array_push($errors, "Invalid email");
  }
  if (empty($password_1)) { array_push($errors, "Password is required"); }
  if ($password_1 != $password_2) {
    array_push($errors, "The two passwords do not match");
  }
    
  if($check == 'unchecked'){
    array_push($errors, "You need to agree with the Terms and Conditions first.");
  }

  $sql = "SELECT * FROM users WHERE email = ? OR username = ?;";
  $stmt = mysqli_stmt_init($db);
  if (!mysqli_stmt_prepare($stmt, $sql)){
      array_push($errors, "Something Went Wrong.");
  }
  else{
        mysqli_stmt_bind_param($stmt, "ss", $email, $username);
        mysqli_stmt_execute($stmt);
      
        $resultData = mysqli_stmt_get_result($stmt);
      
        if($roww = mysqli_fetch_assoc($resultData)){
            if (strtolower($roww['username']) === strtolower($username)) {
                array_push($errors, "Username already exists");
            }

            if ($roww['email'] === $email) {
                array_push($errors, "Email already exists");
            }
        }
        else{
            $query = "INSERT INTO users (email, username, password) VALUES (?, ?, ?);";
            $stmtt = mysqli_stmt_init($db);
            if (!mysqli_stmt_prepare($stmtt, $query)){
                array_push($errors, "Something Went Wrong.");
            }
            if (count($errors) == 0) {
                $hashedpass = password_hash($password_1, PASSWORD_DEFAULT);
            
                mysqli_stmt_bind_param($stmtt, "sss", $email, $username, $hashedpass);
                mysqli_stmt_execute($stmtt);
            
                mysqli_stmt_close($stmtt);
            
                $_SESSION['username'] = strtoupper($username);
                $_SESSION['success'] = "You are now logged in";
                header('location: home.php');
            }
        }
  }
  mysqli_stmt_close($stmt);
  
}
// LOGIN USER
if (isset($_POST['login_user'])) {
  $username = $_POST['username'];
  $password = $_POST['password'];

  if (empty($username)) {
    array_push($errors, "Username is required");
  }
  if (empty($password)) {
    array_push($errors, "Password is required");
  }
      
  $quer = "SELECT * FROM users WHERE username = ?;";
  $stmttt = mysqli_stmt_init($db);
  
  if (!mysqli_stmt_prepare($stmttt, $quer)){
       array_push($errors, "Something Went Wrong.");
  }

  if (count($errors) == 0) {
    mysqli_stmt_bind_param($stmttt, "s", $username);
    mysqli_stmt_execute($stmttt);
    
    $resultDataa = mysqli_stmt_get_result($stmttt);
    
    if ($row = mysqli_fetch_assoc($resultDataa)) {
            $checkpass = password_verify($password, $row["password"]);
            if($checkpass === true){
                $_SESSION['username'] = $row["username"];
                $_SESSION['success'] = "You are now logged in";
                header('location: home.php');
            }
            else{
                array_push($errors, "Wrong password.");
            }
        }
    else{
                array_push($errors, "User not found");
        }
    mysqli_stmt_close($stmttt);
  }
}

?>

If this is not invulnerable to injections, what changes should I make? Also, I would like to use mysqli instead of pdo, if possible.

takuzo
  • 1
  • If you use prepared statements and parameters, and never substitute variables into the queries, then you're protected from SQL injection. – Barmar Jul 09 '21 at 16:10
  • So this is invulnerable to sql injection? I'm new to this stuff and I don't know if I missed anything/. – takuzo Jul 09 '21 at 16:12
  • That's really all there is to it. You could have other problems, but not SQL injection. – Barmar Jul 09 '21 at 16:14
  • This code might not be, as I don't see you injecting PHP variables anywhere in the SQL, but the mere fact that you are asking means that your code might be vulnerable. – Dharman Jul 09 '21 at 16:14
  • If you are only starting to learn PHP then you should learn PDO instead of mysqli. PDO is much easier and more suitable for beginners. Start here https://phpdelusions.net/pdo & https://websitebeaver.com/php-pdo-prepared-statements-to-prevent-sql-injection – Dharman Jul 09 '21 at 16:15

0 Answers0