I would kindly ask you to review the following code and tell me if it's enough to prevent most of SQL injection and XSS attacks.
- SQL injection: treated via PDO prepared statements;
- XSS: All user's inputs are parsed in every documents through
htmlentities
+ENT_QUOTES
+'UTF-8'
;
Here is an example of my code:
<?php
$db_hostname='localhost';
$db_username='user';
$db_password='pass';
$db_dbname='db_name';
$db_conn_str="mysql:host=" . $db_hostname . ";dbname=" . $db_dbname;
try {
$db = new PDO($db_conn_str, $db_username, $db_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $db->prepare("SELECT * FROM users_db WHERE uname = ?");
$stmt->bindValue(1, $_SESSION['Kuser']);
$stmt->execute();
$result = $stmt->fetchAll();
if (count($result) > 0) {
$fnameR = htmlentities($result[0]['fname'], ENT_QUOTES, 'UTF-8');
$lnameR = htmlentities($result[0]['lname'], ENT_QUOTES, 'UTF-8');
$addressR = htmlentities($result[0]['address'], ENT_QUOTES, 'UTF-8');
$emailR = htmlentities($result[0]['email'], ENT_QUOTES, 'UTF-8');
$db=null;
}
else {
$db=null;
header('Location: access.php');
}
}
catch (PDOException $e) {
$db=null;
header('Location: error.php');
}
?>
This code snippet retrieves if an user exist in the database and if so, fetches some data from the table that get parsed in the html document.
Please also be aware of the following:
- Absolutely no input in the application from user A is visible to user B;
- The only user inputs visible in any html documents of the application is their own information stored in the database like in the above code block where an user can modify their personal information through a standard html form;
- The only file in the application that parses input from other users is accessed by me, and the information is treated via
htmlentities
as well. It is a page that generates a html table with the list of usernames like so:
while($row = mysqli_fetch_assoc($resultSHOW)) {
echo "<tr><td bgcolor='#FFF'>" . htmlentities($row['uname'], ENT_QUOTES, 'UTF-8'). "</td></tr>";
}
- Any interaction between the user and the MySQL database are operated with MySQL credentials that has only
SELECT
UPDATE
andINSERT
privileges. All other SQL commands are disabled for them. - All of PHP and MySQL errors messages are customized. The user is in fact redirected to a generic error page when an error occurs.
So the question remains, is all of the above enough to prevent most of SQL injection and XSS attacks? I understand that it's really hard to prevent every security threats, I am simply looking in preventing most of the case here.
Also, concerning session hijacking, my application works in a way that when an user log in, a custom session variable is created and saved. Then, every page this user visit checks if this session variable exists and allow the user to access the account section of the application like so:
<?php
if (!isset($_SESSION['user'])) {
header('Location: login.php');
}
?>
Where $_SESSION['user']
is the user's username.
It is the only tool my application uses to check if an user has actually log in! If this variable is not set, the user is redirected to the login.php page, otherwise, they can navigate through the account section of the application.
Reading many documents available online, I understand that this can be really vulnerable to session hijacking. What would be the best approach regarding that? I want to keep it as simple as possible, I am not interested in using cookies as they are vulnerable to cookie thefts. But if you think it is better so, I will kindly listen to your arguments.