CSRF Token

Upon login, issue the user a CSRF token (in their session). This token should be provided when completing sensitive actions (e.g. deleting companies/clients, changing their password, etc.)

Ref: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern
This commit is contained in:
Marcus Hill
2022-05-01 18:43:53 +01:00
parent eee7c0b204
commit 61777116a9
9 changed files with 42 additions and 4 deletions

View File

@@ -22,7 +22,7 @@
<input class="form-control" type="text" id="clientNameProvided<?php echo $client_id ?>" onkeyup="validateClientNameDelete(<?php echo $client_id ?>)" placeholder="Please enter: '<?php echo $client_name; ?>'"> <input class="form-control" type="text" id="clientNameProvided<?php echo $client_id ?>" onkeyup="validateClientNameDelete(<?php echo $client_id ?>)" placeholder="Please enter: '<?php echo $client_name; ?>'">
</div> </div>
<button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button>
<a class="btn btn-danger btn-lg px-5 disabled" id="clientDeleteButton<?php echo $client_id ?>" href="post.php?delete_client=<?php echo $client_id; ?>">Yes, Delete!</a> <a class="btn btn-danger btn-lg px-5 disabled" id="clientDeleteButton<?php echo $client_id ?>" href="post.php?delete_client=<?php echo $client_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">Yes, Delete!</a>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -101,7 +101,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="post.php?archive_company=<?php echo $company_id; ?>">Archive</a> <a class="dropdown-item text-danger" href="post.php?archive_company=<?php echo $company_id; ?>">Archive</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item text-danger text-bold" href="post.php?delete_company=<?php echo $company_id; ?>">Delete</a> <a class="dropdown-item text-danger text-bold" href="post.php?delete_company=<?php echo $company_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">Delete</a>
</div> </div>
</div> </div>
</td> </td>

View File

@@ -405,4 +405,18 @@ function getDomainExpirationDate($name){
return '0000-00-00'; return '0000-00-00';
} }
// Cross-Site Request Forgery check for sensitive functions
// Validates the CSRF token provided matches the one in the users session
function validateCSRFToken($token){
if(hash_equals($token, $_SESSION['csrf_token'])){
return true;
}
else{
$_SESSION['alert_type'] = "warning";
$_SESSION['alert_message'] = "CSRF token verification failed. Try again, or log out to refresh your token.";
header("Location: index.php");
exit();
}
}
?> ?>

View File

@@ -63,6 +63,9 @@ if(isset($_POST['login'])){
$user_name = $row['user_name']; $user_name = $row['user_name'];
$user_id = $row['user_id']; $user_id = $row['user_id'];
// CSRF Token
$_SESSION['csrf_token'] = keygen();
// Setup encryption session key // Setup encryption session key
if (isset($row['user_specific_encryption_ciphertext']) && $row['user_role'] > 1) { if (isset($row['user_specific_encryption_ciphertext']) && $row['user_role'] > 1) {
$user_encryption_ciphertext = $row['user_specific_encryption_ciphertext']; $user_encryption_ciphertext = $row['user_specific_encryption_ciphertext'];

View File

@@ -58,6 +58,9 @@ if(isset($_POST['add_user'])){
exit(); exit();
} }
// CSRF Check
validateCSRFToken($_POST['csrf_token']);
$name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name']))); $name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name'])));
$email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email']))); $email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email'])));
$password = password_hash($_POST['password'], PASSWORD_DEFAULT); $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
@@ -140,6 +143,9 @@ if(isset($_POST['edit_user'])){
exit(); exit();
} }
// CSRF Check
validateCSRFToken($_POST['csrf_token']);
$user_id = intval($_POST['user_id']); $user_id = intval($_POST['user_id']);
$name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name']))); $name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name'])));
$email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email']))); $email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email'])));
@@ -238,6 +244,9 @@ if(isset($_POST['edit_profile'])){
exit(); exit();
} }
// CSRF Check
validateCSRFToken($_POST['csrf_token']);
$user_id = intval($_POST['user_id']); $user_id = intval($_POST['user_id']);
$name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name']))); $name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name'])));
$email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email']))); $email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email'])));
@@ -375,6 +384,9 @@ if(isset($_GET['archive_user'])){
exit(); exit();
} }
// CSRF Check
validateCSRFToken($_GET['csrf_token']);
// Variables from GET // Variables from GET
$user_id = intval($_GET['archive_user']); $user_id = intval($_GET['archive_user']);
$password = password_hash(key32gen(), PASSWORD_DEFAULT); $password = password_hash(key32gen(), PASSWORD_DEFAULT);
@@ -695,6 +707,9 @@ if(isset($_GET['delete_company'])){
exit(); exit();
} }
// CSRF Check
validateCSRFToken($_GET['csrf_token']);
$company_id = intval($_GET['delete_company']); $company_id = intval($_GET['delete_company']);
//Get Company Name //Get Company Name
@@ -760,7 +775,7 @@ if(isset($_GET['delete_company'])){
$_SESSION['alert_type'] = "danger"; $_SESSION['alert_type'] = "danger";
$_SESSION['alert_message'] = "Company <strong>$company_name</strong> deleted"; $_SESSION['alert_message'] = "Company <strong>$company_name</strong> deleted";
header("Location: logout.php"); header("Location: post.php?logout");
} }
@@ -1456,6 +1471,9 @@ if(isset($_GET['delete_client'])){
exit(); exit();
} }
// CSRF Check
validateCSRFToken($_GET['csrf_token']);
$client_id = intval($_GET['delete_client']); $client_id = intval($_GET['delete_client']);
//Get Client Name //Get Client Name

View File

@@ -21,6 +21,7 @@ $sql_recent_logs = mysqli_query($mysqli,"SELECT * FROM logs
<div class="card-body"> <div class="card-body">
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<input type="hidden" name="user_id" value="<?php echo $session_user_id; ?>"> <input type="hidden" name="user_id" value="<?php echo $session_user_id; ?>">
<input type="hidden" name="existing_file_name" value="<?php echo $session_avatar; ?>"> <input type="hidden" name="existing_file_name" value="<?php echo $session_avatar; ?>">

View File

@@ -8,6 +8,7 @@
</button> </button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">
<div class="form-group"> <div class="form-group">

View File

@@ -8,7 +8,7 @@
<h6 class="mb-4 text-secondary">Do you really want to <b>archive <?php echo $user_name; ?></b>? This process cannot be undone.</h6> <h6 class="mb-4 text-secondary">Do you really want to <b>archive <?php echo $user_name; ?></b>? This process cannot be undone.</h6>
<h6 class="mb-4 text-secondary"><?php echo $user_name ?> will no longer be able to login or use ITFlow, but all associated content will remain accessible.</h6> <h6 class="mb-4 text-secondary"><?php echo $user_name ?> will no longer be able to login or use ITFlow, but all associated content will remain accessible.</h6>
<button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-outline-secondary btn-lg px-5 mr-4" data-dismiss="modal">Cancel</button>
<a class="btn btn-danger btn-lg px-5" href="post.php?archive_user=<?php echo $user_id; ?>">Yes, archive!</a> <a class="btn btn-danger btn-lg px-5" href="post.php?archive_user=<?php echo $user_id; ?>&csrf_token=<?php echo $_SESSION['csrf_token'] ?>">Yes, archive!</a>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -8,6 +8,7 @@
</button> </button>
</div> </div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off"> <form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>"> <input type="hidden" name="user_id" value="<?php echo $user_id; ?>">
<input type="hidden" name="existing_file_name" value="<?php echo "$user_avatar"; ?>"> <input type="hidden" name="existing_file_name" value="<?php echo "$user_avatar"; ?>">
<div class="modal-body bg-white"> <div class="modal-body bg-white">