I'm developing my own PHP framework. It seems all the security articles I have read use vastly different methods for user authentication than I do so I could use some help in finding security holes.
Some information that might be useful before I start. I use mod_rewrite for my MVC url's. Passwords are encrypted with 24 character salt unique to each user. mysql_real_escape_string and/or variable typecasting on everything going in, and htmlspecialchars on everything coming out.
Step-by step process:
Top of every page:
session_start();
session_regenerate_id();
If user logs in via login form, generate new random token to put in user's MySQL row. Hash is generated based on user's salt (from when they first registered) and the new token. Store the hash and plaintext username in session variables, and duplicate in cookies if 'Remember me' is checked.
On every page, check for cookies. If cookies set, copy their values into session variables. Then compare $_SESSION['name'] and $_SESSION['hash'] against MySQL database. Destroy all cookies and session variables if they don't match so they have to log in again.
If login is valid, some of the user's information from the MySQL database is stored in an array for easy access. So far, I've assumed that this array is clean so when limiting user access I refer to user.rank and deny access if it's below what's required for that page.
I've tried to test all the common attacks like XSS and CSRF, but maybe I'm just not good enough at hacking my own site! My system seems way too simple for it to actually be secure (the security code is only 100 lines long). What am I missing?
Edit: For calling functions from the controller, anything that uses anything other than SELECT queries will require $_POST data to confirm a delete, for example, in addition to the user rank requirements.
I've also spent alot of time searching for the vulnerabilities with mysql_real_escape string but I haven't found any information that is up-to-date (everything is from several years ago at least and has apparently been fixed). All I know is that the problem was something to do with encoding. If that problem still exists today, how can I avoid it?
The encrypt function I borrowed from somewhere and modified:
public function encrypt($str, $salt = NULL) {
if ($salt == NULL) $salt = substr(md5(uniqid(rand(), true)), 0, 24);
else $salt = substr($salt, 0, 24);
return $salt.sha1($salt.$str);
}