Add CSRF Checks in the client portal

This commit is contained in:
johnnyq
2026-03-07 13:11:08 -05:00
parent 6d2cb0aea3
commit 8de7b20ba1
10 changed files with 58 additions and 18 deletions

View File

@@ -27,9 +27,7 @@ if ($session_contact_primary == 0 && !$session_contact_is_technical_contact) {
<div class="col-md-6">
<form action="post.php" method="post">
<!-- Prevent undefined checkbox errors on submit -->
<input type="hidden" name="contact_billing" value="0">
<input type="hidden" name="contact_technical" value="0">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group">
<label>Name <strong class="text-danger">*</strong></label>

View File

@@ -57,10 +57,8 @@ if ($row) {
<div class="col-md-6">
<form action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="contact_id" value="<?php echo $contact_id; ?>">
<!-- Prevent undefined checkbox errors on submit -->
<input type="hidden" name="contact_billing" value="0">
<input type="hidden" name="contact_technical" value="0">
<div class="form-group">
<label>Name <strong class="text-danger">*</strong></label>

View File

@@ -90,6 +90,7 @@ $documents_sql = mysqli_query($mysqli, "SELECT document_id, document_name, docum
</button>
</div>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body bg-white">
<div class="form-group">
<label>Document Name <strong class="text-danger">*</strong></label>
@@ -136,6 +137,7 @@ $documents_sql = mysqli_query($mysqli, "SELECT document_id, document_name, docum
</button>
</div>
<form action="post.php" method="post" enctype="multipart/form-data" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="modal-body bg-white">
<div class="form-group">
<label>Document Name <strong class="text-danger">*</strong></label>

View File

@@ -12,6 +12,8 @@ require_once 'functions.php';
if (isset($_POST['add_ticket'])) {
validateCSRFToken($_POST['csrf_token']);
$subject = sanitizeInput($_POST['subject']);
$details = mysqli_real_escape_string($mysqli, ($_POST['details']));
$category = intval($_POST['category']);
@@ -82,6 +84,8 @@ if (isset($_POST['add_ticket'])) {
if (isset($_POST['add_ticket_comment'])) {
validateCSRFToken($_POST['csrf_token']);
$ticket_id = intval($_POST['ticket_id']);
$comment = mysqli_real_escape_string($mysqli, $_POST['comment']);
@@ -187,6 +191,8 @@ if (isset($_POST['add_ticket_comment'])) {
if (isset($_GET['approve_ticket_task'])) {
validateCSRFToken($_GET['csrf_token']);
$task_id = intval($_GET['approve_ticket_task']);
$approval_id = intval($_GET['approval_id']);
$url_key = sanitizeInput($_GET['approval_url_key']);
@@ -224,6 +230,8 @@ if (isset($_GET['approve_ticket_task'])) {
if (isset($_POST['add_ticket_feedback'])) {
validateCSRFToken($_POST['csrf_token']);
$ticket_id = intval($_POST['ticket_id']);
$feedback = sanitizeInput($_POST['add_ticket_feedback']);
@@ -254,6 +262,8 @@ if (isset($_POST['add_ticket_feedback'])) {
if (isset($_GET['resolve_ticket'])) {
validateCSRFToken($_GET['csrf_token']);
$ticket_id = intval($_GET['resolve_ticket']);
// Get ticket details for logging
@@ -286,6 +296,9 @@ if (isset($_GET['resolve_ticket'])) {
}
if (isset($_GET['reopen_ticket'])) {
validateCSRFToken($_GET['csrf_token']);
$ticket_id = intval($_GET['reopen_ticket']);
// Get ticket details for logging
@@ -319,6 +332,8 @@ if (isset($_GET['reopen_ticket'])) {
if (isset($_GET['close_ticket'])) {
validateCSRFToken($_GET['csrf_token']);
$ticket_id = intval($_GET['close_ticket']);
// Get ticket details for logging
@@ -363,6 +378,8 @@ if (isset($_GET['logout'])) {
if (isset($_POST['edit_profile'])) {
validateCSRFToken($_POST['csrf_token']);
$new_password = $_POST['new_password'];
if (!empty($new_password)) {
@@ -379,14 +396,16 @@ if (isset($_POST['edit_profile'])) {
if (isset($_POST['add_contact'])) {
validateCSRFToken($_POST['csrf_token']);
if ($session_contact_primary == 0 && !$session_contact_is_technical_contact) {
redirect("post.php?logout");
}
$contact_name = sanitizeInput($_POST['contact_name']);
$contact_email = sanitizeInput($_POST['contact_email']);
$contact_technical = intval($_POST['contact_technical']);
$contact_billing = intval($_POST['contact_billing']);
$contact_technical = intval($_POST['contact_technical'] ?? 0);
$contact_billing = intval($_POST['contact_billing'] ?? 0);
$contact_auth_method = sanitizeInput($_POST['contact_auth_method']);
// Check the email isn't already in use
@@ -426,6 +445,8 @@ if (isset($_POST['add_contact'])) {
if (isset($_POST['edit_contact'])) {
validateCSRFToken($_POST['csrf_token']);
if ($session_contact_primary == 0 && !$session_contact_is_technical_contact) {
redirect("post.php?logout");
}
@@ -433,8 +454,8 @@ if (isset($_POST['edit_contact'])) {
$contact_id = intval($_POST['contact_id']);
$contact_name = sanitizeInput($_POST['contact_name']);
$contact_email = sanitizeInput($_POST['contact_email']);
$contact_technical = intval($_POST['contact_technical']);
$contact_billing = intval($_POST['contact_billing']);
$contact_technical = intval($_POST['contact_technical'] ?? 0);
$contact_billing = intval($_POST['contact_billing'] ?? 0);
$contact_auth_method = sanitizeInput($_POST['contact_auth_method']);
// Get the existing contact_user_id - we look it up ourselves so the user can't just overwrite random users
@@ -476,6 +497,8 @@ if (isset($_POST['edit_contact'])) {
if (isset($_GET['add_payment_by_provider'])) {
validateCSRFToken($_GET['csrf_token']);
$invoice_id = intval($_GET['invoice_id']);
$saved_payment_id = intval($_GET['add_payment_by_provider']);
@@ -672,6 +695,8 @@ if (isset($_GET['add_payment_by_provider'])) {
if (isset($_POST['create_stripe_customer'])) {
validateCSRFToken($_POST['csrf_token']);
if ($session_contact_primary == 0 && !$session_contact_is_billing_contact) {
redirect("post.php?logout");
}
@@ -758,6 +783,8 @@ if (isset($_POST['create_stripe_customer'])) {
if (isset($_GET['create_stripe_checkout'])) {
validateCSRFToken($_GET['csrf_token']);
// This page is called by autopay_setup_stripe.js, returns a Checkout Session client_secret
if ($session_contact_primary == 0 && !$session_contact_is_billing_contact) {
@@ -828,6 +855,8 @@ if (isset($_GET['create_stripe_checkout'])) {
if (isset($_GET['stripe_save_card'])) {
validateCSRFToken($_GET['csrf_token']);
if ($session_contact_primary == 0 && !$session_contact_is_billing_contact) {
redirect("post.php?logout");
}
@@ -957,6 +986,8 @@ if (isset($_GET['stripe_save_card'])) {
if (isset($_GET['delete_saved_payment'])) {
validateCSRFToken($_GET['csrf_token']);
if ($session_contact_primary == 0 && !$session_contact_is_billing_contact) {
redirect("post.php?logout");
}
@@ -1059,6 +1090,8 @@ if (isset($_GET['delete_saved_payment'])) {
if (isset($_POST['set_recurring_payment'])) {
validateCSRFToken($_POST['csrf_token']);
$recurring_invoice_id = intval($_POST['recurring_invoice_id']);
$saved_payment_id = intval($_POST['saved_payment_id']);
@@ -1111,6 +1144,8 @@ if (isset($_POST['set_recurring_payment'])) {
if (isset($_POST['client_add_document'])) {
validateCSRFToken($_POST['csrf_token']);
// Permission check - only primary or technical contacts can create documents
if ($session_contact_primary == 0 && !$session_contact_is_technical_contact) {
redirect("post.php?logout");
@@ -1155,6 +1190,8 @@ if (isset($_POST['client_add_document'])) {
if (isset($_POST['client_upload_document'])) {
validateCSRFToken($_POST['csrf_token']);
// Permission check - only primary or technical contacts can upload documents
if ($session_contact_primary == 0 && !$session_contact_is_technical_contact) {
redirect("post.php?logout");

View File

@@ -31,6 +31,7 @@ require_once 'includes/inc_all.php';
<div class="col-md-6">
<h4>Password</h4>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group">
<label>New Password</label>
<div class="input-group">
@@ -47,4 +48,3 @@ require_once 'includes/inc_all.php';
<?php
require_once 'includes/footer.php';

View File

@@ -80,6 +80,7 @@ $payment_provider_threshold = floatval($row['payment_provider_threshold']);
<?php $sql = mysqli_query($mysqli, "SELECT * FROM client_saved_payment_methods WHERE saved_payment_client_id = $session_client_id");
if (mysqli_num_rows($sql) > 0) { ?>
<form class="form" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="set_recurring_payment" value="1">
<input type="hidden" name="recurring_invoice_id" value="<?php echo $recurring_invoice_id; ?>">
<select class="form-control select2" name="saved_payment_id" onchange="this.form.submit()">

View File

@@ -69,6 +69,7 @@ if (!$stripe_public_key || !$stripe_secret_key) {
<br><br>
<form action="post.php" method="POST">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group">
<button type="submit" class="btn btn-success" name="create_stripe_customer"><strong><i class="fas fa-check mr-2"></i>I grant consent for automatic payments</strong></button>
@@ -108,7 +109,7 @@ if (!$stripe_public_key || !$stripe_secret_key) {
$exp_year = nullable_htmlentities($pm->card->exp_year);
echo "<li><i class='$payment_icon fa-2x mr-2'></i>$brand x<strong>$last4</strong> | Exp. $exp_month/$exp_year";
echo " <a class='text-danger' href='post.php?delete_saved_payment={$method['saved_payment_id']}'>Remove</a></li>";
echo " <a class='text-danger' href='post.php?delete_saved_payment={$method['saved_payment_id']}&csrf_token={$_SESSION['csrf_token']}'>Remove</a></li>";
}
} catch (Exception $e) {
$error = $e->getMessage();

View File

@@ -97,7 +97,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<div class="card-tools">
<?php
if (empty($ticket_resolved_at) && $task_count == $completed_task_count) { ?>
<a href="post.php?resolve_ticket=<?php echo $ticket_id; ?>" class="btn btn-sm btn-outline-success float-right text-white confirm-link"><i class="fas fa-fw fa-check text-success"></i> Resolve ticket</a>
<a href="post.php?resolve_ticket=<?php echo $ticket_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-sm btn-outline-success float-right text-white confirm-link"><i class="fas fa-fw fa-check text-success"></i> Resolve ticket</a>
<?php } ?>
</div>
</div>
@@ -176,7 +176,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<li>
<?php echo $task_name;
if ($contact_can_approve) { ?> - <a href="post.php?approve_ticket_task=<?= $task_id ?>&approval_id=<?= $approval_id ?>&approval_url_key=<?= $approval_url_key ?>" class="confirm-link">Approve task</a> <?php }
if ($contact_can_approve) { ?> - <a href="post.php?approve_ticket_task=<?= $task_id ?>&approval_id=<?= $approval_id ?>&approval_url_key=<?= $approval_url_key ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="confirm-link">Approve task</a> <?php }
else {?> - Please ask your <?= $approval_type ?> contact to approve this task <?php } ?>
</li>
@@ -198,6 +198,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<!-- Reply -->
<form action="post.php" enctype="multipart/form-data" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id ?>">
<div class="form-group">
<textarea class="form-control tinymce" name="comment" placeholder="Add comments.."></textarea>
@@ -216,11 +217,11 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<div class="col-6">
<div class="row">
<div class="col">
<a href="post.php?reopen_ticket=<?php echo $ticket_id; ?>" class="btn btn-secondary btn-lg"><i class="fas fa-fw fa-redo text-white"></i> Reopen ticket</a>
<a href="post.php?reopen_ticket=<?php echo $ticket_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-secondary btn-lg"><i class="fas fa-fw fa-redo text-white"></i> Reopen ticket</a>
</div>
<div class="col">
<a href="post.php?close_ticket=<?php echo $ticket_id; ?>" class="btn btn-success btn-lg confirm-link"><i class="fas fa-fw fa-gavel text-white"></i> Close ticket</a>
<a href="post.php?close_ticket=<?php echo $ticket_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>" class="btn btn-success btn-lg confirm-link"><i class="fas fa-fw fa-gavel text-white"></i> Close ticket</a>
</div>
</div>
</div>
@@ -231,6 +232,7 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<h4>Ticket closed. Please rate your ticket</h4>
<form action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id ?>">
<button type="submit" class="btn btn-primary btn-lg" name="add_ticket_feedback" value="Good" onclick="this.form.submit()">

View File

@@ -25,6 +25,7 @@ $sql_assets = mysqli_query($mysqli, "SELECT asset_id, asset_name, asset_type FRO
<div class="col-md-8">
<form action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<div class="form-group">
<label>Subject <strong class="text-danger">*</strong></label>

View File

@@ -71,7 +71,7 @@ $balance = $invoice_amounts - $amount_paid;
$payment_provider_name = nullable_htmlentities($row['payment_provider_name']);
?>
<a class="dropdown-item confirm-link" href="post.php?add_payment_by_provider=<?php echo $saved_payment_provider_id; ?>&invoice_id=<?php echo $invoice_id; ?>"><?php echo "$payment_provider_name | $saved_payment_description"; ?></a>
<a class="dropdown-item confirm-link" href="post.php?add_payment_by_provider=<?php echo $saved_payment_provider_id; ?>&invoice_id=<?php echo $invoice_id; ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>"><?php echo "$payment_provider_name | $saved_payment_description"; ?></a>
<?php }
} ?>
</div>
@@ -185,7 +185,7 @@ $balance = $invoice_amounts - $amount_paid;
?>
<a class="dropdown-item confirm-link"
href="post.php?add_payment_by_provider=<?= $saved_payment_id ?>&invoice_id=<?= $invoice_id ?>">
href="post.php?add_payment_by_provider=<?= $saved_payment_id ?>&invoice_id=<?= $invoice_id ?>&csrf_token=<?= $_SESSION['csrf_token'] ?>">
<i class="<?php echo $payment_icon; ?> text-secondary mr-2"></i><?= $saved_payment_description ?>
</a>
<?php }