Could anyone tell me if this code is well written and if it has bugs / vulnerabilities?
class.user.php:
<?php
class User {
public $authorized = false;
public $uid;
public $username;
public function __construct() {
$this->db = new PDO($dsn, $db_user, $db_pass);
$this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
if (isset($_SESSION['uid'])) {
$this->authorizsed = true;
$this->uid = $_SESSION['uid'];
$this->username = $_SESSION['username'];
} else if (isset($_POST['reset'])) {
$user = $_POST['reset'];
$this->reset($user);
} else if (isset($_POST['username']) && isset($_POST['password'])) {
$user = $_POST['username'];
$pass = $_POST['password'];
$this->login($user, $pass);
}
}
private function login($user, $pass) {
$st = $this->db->prepare('SELECT `uid`, `username`, `password`
FROM users
WHERE username = :u');
$st->execute(array(':u' => $user));
$row = $st->fetch();
if ($row && $row->password == sha1($pass)) {
$this->authorized = true;
$this->uid = $row->uid;
$_SESSION['uid'] = $this->uid;
$this->username = $row->username;
$_SESSION['username'] = $this->username;
return true;
} else {
return false;
}
}
private function reset($user) {
$st = $this->db->prepare('SELECT `uid`, `username`, `email`
FROM users
WHERE username = :u');
$st->execute(array(':u' => $user));
$row = $st->fetch();
if ($row) {
$token = $this->generateRequest();
$st = $this->db->prepare('UPDATE users SET `reset` = :reset, password = 0 WHERE uid = :uid LIMIT 1');
$status = $st->execute(array(':uid' => $row->uid, ':reset' => $token));
$body = "We received a request for your account details.<br/><br/>Username: {$row->username}<br/>To reset your password, click on this link: <a href='http://www.example.org/?reset={$token}'>http://www.example.org/?reset={$token}/a>";
$to = $row->email;
$subject = 'Password request';
$from = '[email protected]';
// To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
// Create email headers
$headers .= 'From: '.$from."\r\n".
'Reply-To: '.$from."\r\n";
mail($to, $subject, $body, $headers)
}
}
private function generateRequest() {
$token = md5(openssl_random_pseudo_bytes(32));
return $token;
}
}
?>
index.php:
<?php
session_start();
require('class.user.php');
$user = new User();
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Login</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<?php
if ($user->authorized):
?>
Welcome, <?=$user->username;?>!
<?php
elseif (isset($_GET['forgot'])):
?>
<div class="module form-module">
<div class="form">
<h2>Reset password</h2>
<?php if (isset($_POST['reset'])): ?>
<div class="success">Email sent</div>
<?php endif; ?>
<form method="POST">
<input type="text" name="reset" placeholder="Username"/>
<button>Reset</button>
</form>
</div>
<div class="cta"><a href="./">Login</a></div>
</div>
<?php
else:
?>
<div class="module form-module">
<div class="form">
<h2>Login to your account</h2>
<?php if (isset($_POST['username']) && isset($_POST['password'])): ?>
<div class="error">Invalid login</div>
<?php endif; ?>
<form method="POST">
<input type="text" name="username" placeholder="Username"/>
<input type="password" name="password" placeholder="Password"/>
<button>Login</button>
</form>
</div>
<div class="cta"><a href="?forgot">Forgot your password?</a></div>
</div>
<?php
endif;
?>
</body>
</html>
Is it possible that somehow, someone bypass the reset system ?
$dsn, $db_user, $db_pass
isn't in the local scope of__construct()
, so you won't have a connection to your database. \$\endgroup\$