I am about to launch my website and security is important so i wanted to outline what I have done to secure the site. Please correct me if I am wrong and if I need something else:
- To connect to our server, I have a two-factor authenitcation enabled via VPN.
- The site uses SSL
- Data is encrypted at rest.
- I have a log monitoring tool
- WHen users enter data into the database i use mysql_real_escape_string(); and when i display user data i use htmlspecialchars();
Passwords are stored using md5 encryption.
Sample insert query:
// I use these on every page
$username = removeBadChars($_SESSION["username"]);
$password = removeBadChars($_SESSION["password"]);
//Sanitized data
$_SESSION["username"] = $username;
$_SESSION["password"] = $password;
//Query to display
$sql = "select `User_name`, `User_id`, `User_kind` from `clientele`
where `username` = '$username' AND `password`='$password'";
$query = mysql_query($sql) or die ("Error: ".mysql_error());
while ($row = mysql_fetch_array($query)){
$name = htmlspecialchars($row['User_name']);
$uid = htmlspecialchars($row['User_id']);
$uis = htmlspecialchars($row['User_kind']);
}
mysql_free_result($query);
//Insert Query
$title = mysql_real_escape_string($_POST['title']);
$comment = mysql_real_escape_string($_POST['comment']);
$insert = "INSERT INTO table (Title, Comment)
VALUES ('".$title."', '".$comment."')";
$query = mysql_query($insert) or die ("Error: ".mysql_error());
- Use a stronger hash function (e.g.
sha256
)
- Append a salt (random value for every user) to the password before hashing it
- Use prepared statements (
MySQLi
) instead, to avoid the possibility of forgetting to escape data before entering it into the database
Do not store user information in $_SESSION. Instead, store a session variable that means nothing to the outside world, changes every time someone logs in, and links to the user account. - This only applies to cookies. drinks some caffeine
- Be careful putting data from user in attribute values (e.g.
<span title="FULLNAME">
), as additional escaping is needed (quotes, spaces if not using quotes, etc)
Note: This list is not exhaustive. It only lists things I noticed that were wrong with the short snippets you provided.
For safety you should probably use a PDO or mysqli_
functions and skip that old-school mysql_
junk, it's no longer being developed. Here's how to use the PDO:
$pdo = new PDO('mysql:host=localhost;dbname=whatever', $username, $password);
$statement = $pdo->prepare('select `User_name`, `User_id`, `User_kind` from `users`
where `username` = :user AND `password`= AES_ENCRYPT(:pass,:user)');
$statement->bindParam(':user', $_GET['user']);
$statement->bindParam(':pass', $_GET['pass']);
$results = $statement->execute();
var_dump($results->fetchAll());
the parameters are much safer because when you bindParam
it automagically validates. Others have mentioned using md5
hashing, but there are plenty of databases for "decoding" them and also rainbow table attacks, so they're not very secure. Here I'm using mysql's AES_ENCRYPT
for the password, and using the username as the key for demonstration purposes, you'd probably want to generate your own key and store it somewhere, because you can AES_DECRYPT
with that... There are libraries for better encryption you should check out, like scrypt.
Whatever you do, do not use addslashes()
it's insecure
On top of that you should look into securing your server's OS and Apache in other ways, like making not advertise version numbers and running apache as it's own users etc. Check out the Open Web Security Project website for tons of security info.