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; ?>'">
</div>
<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>

View File

@ -101,7 +101,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" href="post.php?archive_company=<?php echo $company_id; ?>">Archive</a>
<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>
</td>

View File

@ -405,4 +405,18 @@ function getDomainExpirationDate($name){
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_id = $row['user_id'];
// CSRF Token
$_SESSION['csrf_token'] = keygen();
// Setup encryption session key
if (isset($row['user_specific_encryption_ciphertext']) && $row['user_role'] > 1) {
$user_encryption_ciphertext = $row['user_specific_encryption_ciphertext'];

View File

@ -58,6 +58,9 @@ if(isset($_POST['add_user'])){
exit();
}
// CSRF Check
validateCSRFToken($_POST['csrf_token']);
$name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name'])));
$email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email'])));
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
@ -140,6 +143,9 @@ if(isset($_POST['edit_user'])){
exit();
}
// CSRF Check
validateCSRFToken($_POST['csrf_token']);
$user_id = intval($_POST['user_id']);
$name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name'])));
$email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email'])));
@ -238,6 +244,9 @@ if(isset($_POST['edit_profile'])){
exit();
}
// CSRF Check
validateCSRFToken($_POST['csrf_token']);
$user_id = intval($_POST['user_id']);
$name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name'])));
$email = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['email'])));
@ -375,6 +384,9 @@ if(isset($_GET['archive_user'])){
exit();
}
// CSRF Check
validateCSRFToken($_GET['csrf_token']);
// Variables from GET
$user_id = intval($_GET['archive_user']);
$password = password_hash(key32gen(), PASSWORD_DEFAULT);
@ -695,6 +707,9 @@ if(isset($_GET['delete_company'])){
exit();
}
// CSRF Check
validateCSRFToken($_GET['csrf_token']);
$company_id = intval($_GET['delete_company']);
//Get Company Name
@ -760,7 +775,7 @@ if(isset($_GET['delete_company'])){
$_SESSION['alert_type'] = "danger";
$_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();
}
// CSRF Check
validateCSRFToken($_GET['csrf_token']);
$client_id = intval($_GET['delete_client']);
//Get Client Name

View File

@ -21,6 +21,7 @@ $sql_recent_logs = mysqli_query($mysqli,"SELECT * FROM logs
<div class="card-body">
<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="existing_file_name" value="<?php echo $session_avatar; ?>">

View File

@ -8,6 +8,7 @@
</button>
</div>
<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="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"><?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>
<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>

View File

@ -8,6 +8,7 @@
</button>
</div>
<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="existing_file_name" value="<?php echo "$user_avatar"; ?>">
<div class="modal-body bg-white">