diff --git a/DataBase.php b/DataBase.php index 6d62bd2..c01ec78 100644 --- a/DataBase.php +++ b/DataBase.php @@ -11,6 +11,9 @@ class DataBase protected $password; protected $databasename; + // Whitelist of allowed table names to prevent table-name injection + private $allowed_tables = ['users']; + public function __construct() { $this->connect = null; @@ -23,49 +26,115 @@ public function __construct() $this->databasename = $dbc->databasename; } + /** + * Establish DB connection, return mysqli object or false + */ function dbConnect() { $this->connect = mysqli_connect($this->servername, $this->username, $this->password, $this->databasename); + if (!$this->connect) { + return false; + } + // set charset to avoid charset-related injection issues + mysqli_set_charset($this->connect, 'utf8mb4'); return $this->connect; } + /** + * Basic cleaning for display / storage. Prepared statements handle SQL safety. + */ function prepareData($data) { - return mysqli_real_escape_string($this->connect, stripslashes(htmlspecialchars($data))); + $data = trim($data); + // remove control characters but DO NOT rely on this for SQL safety + $data = filter_var($data, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW); + return $data; + } + + /** + * Validate / whitelist table name. + */ + private function validateTable($table) + { + return in_array($table, $this->allowed_tables, true); } + /** + * Login using prepared statements + */ function logIn($table, $username, $password) { + // validate table name + if (!$this->validateTable($table)) { + return false; + } + + // clean inputs (not for SQL safety — prepared statements handle that) $username = $this->prepareData($username); $password = $this->prepareData($password); - $this->sql = "select * from " . $table . " where username = '" . $username . "'"; - $result = mysqli_query($this->connect, $this->sql); - $row = mysqli_fetch_assoc($result); - if (mysqli_num_rows($result) != 0) { - $dbusername = $row['username']; - $dbpassword = $row['password']; - if ($dbusername == $username && password_verify($password, $dbpassword)) { - $login = true; - } else $login = false; - } else $login = false; - return $login; + // prepared statement: select hashed password for username + $this->sql = "SELECT username, password FROM " . $table . " WHERE username = ? LIMIT 1"; + if (!$stmt = mysqli_prepare($this->connect, $this->sql)) { + return false; + } + mysqli_stmt_bind_param($stmt, "s", $username); + mysqli_stmt_execute($stmt); + $result = mysqli_stmt_get_result($stmt); + if (!$result) { + mysqli_stmt_close($stmt); + return false; + } + + if ($row = mysqli_fetch_assoc($result)) { + $dbusername = $row['username']; + $dbpassword = $row['password']; // hashed password in DB + mysqli_stmt_close($stmt); + if (password_verify($password, $dbpassword)) { + return true; + } else { + return false; + } + } else { + mysqli_stmt_close($stmt); + return false; + } } + /** + * Sign up using prepared statements + */ function signUp($table, $fullname, $email, $username, $password) { + // validate table name + if (!$this->validateTable($table)) { + return false; + } + + // simple cleaning $fullname = $this->prepareData($fullname); $username = $this->prepareData($username); - $password = $this->prepareData($password); $email = $this->prepareData($email); - $password = password_hash($password, PASSWORD_DEFAULT); - $this->sql = - "INSERT INTO " . $table . " (fullname, username, password, email) VALUES ('" . $fullname . "','" . $username . "','" . $password . "','" . $email . "')"; - if (mysqli_query($this->connect, $this->sql)) { - return true; - } else return false; + $password = $this->prepareData($password); + + // validate email + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + return false; + } + + // hash password + $passwordHash = password_hash($password, PASSWORD_DEFAULT); + + // prepared insert + $this->sql = "INSERT INTO " . $table . " (fullname, username, password, email) VALUES (?, ?, ?, ?)"; + if (!$stmt = mysqli_prepare($this->connect, $this->sql)) { + return false; + } + mysqli_stmt_bind_param($stmt, "ssss", $fullname, $username, $passwordHash, $email); + $exec = mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + return $exec ? true : false; } } - ?> diff --git a/login.php b/login.php index b954175..6a4d102 100644 --- a/login.php +++ b/login.php @@ -3,9 +3,16 @@ $db = new DataBase(); if (isset($_POST['username']) && isset($_POST['password'])) { if ($db->dbConnect()) { - if ($db->logIn("users", $_POST['username'], $_POST['password'])) { + $ok = $db->logIn("users", $_POST['username'], $_POST['password']); + if ($ok) { echo "Login Success"; - } else echo "Username or Password wrong"; - } else echo "Error: Database connection"; -} else echo "All fields are required"; + } else { + echo "Username or Password wrong"; + } + } else { + echo "Error: Database connection"; + } +} else { + echo "All fields are required"; +} ?> diff --git a/signup.php b/signup.php index c855fc9..fd0dc42 100644 --- a/signup.php +++ b/signup.php @@ -3,9 +3,16 @@ $db = new DataBase(); if (isset($_POST['fullname']) && isset($_POST['email']) && isset($_POST['username']) && isset($_POST['password'])) { if ($db->dbConnect()) { - if ($db->signUp("users", $_POST['fullname'], $_POST['email'], $_POST['username'], $_POST['password'])) { + $ok = $db->signUp("users", $_POST['fullname'], $_POST['email'], $_POST['username'], $_POST['password']); + if ($ok) { echo "Sign Up Success"; - } else echo "Sign up Failed"; - } else echo "Error: Database connection"; -} else echo "All fields are required"; + } else { + echo "Sign up Failed"; + } + } else { + echo "Error: Database connection"; + } +} else { + echo "All fields are required"; +} ?>