Files
4WDCSA.co.za/process_eft.php
twotalesanimation 1ef4d06627 Phase 1: Implement CSRF protection, input validation, and rate limiting
Major security improvements:
- Added CSRF token generation, validation, and cleanup functions
- Implemented comprehensive input validators (email, phone, name, date, amount, ID, file uploads)
- Added rate limiting with login attempt tracking and account lockout (5 failures = 15 min lockout)
- Implemented session fixation protection with session_regenerate_id() and 30-min timeout
- Fixed SQL injection in getResultFromTable() with whitelisted columns/tables
- Added audit logging for security events
- Applied CSRF validation to all 7 process_*.php files
- Applied input validation to critical endpoints (login, registration, bookings, application)
- Created database migration for login_attempts, audit_log tables and locked_until column

Modified files:
- functions.php: +500 lines of security functions
- validate_login.php: Added CSRF, rate limiting, session hardening
- register_user.php: Added CSRF, input validation, registration rate limiting
- process_*.php (7 files): Added CSRF token validation
- Created migration: 001_phase1_security_schema.sql

Next steps: Add CSRF tokens to form templates, harden file uploads, create testing checklist
2025-12-03 11:28:53 +02:00

98 lines
3.1 KiB
PHP

<?php
require_once("env.php");
require_once("session.php");
require_once("connection.php");
require_once("functions.php");
checkAdmin();
// CSRF Token Validation for POST requests
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
auditLog($_SESSION['user_id'] ?? null, 'CSRF_VALIDATION_FAILED', 'efts', null, ['endpoint' => 'process_eft.php']);
http_response_code(403);
die('Security token validation failed.');
}
}
if (!isset($_GET['token']) || empty($_GET['token'])) {
die("Invalid request.");
}
$token = $_GET['token'];
// echo $token;
$eft_id = decryptData($token, $salt);
$user = getUserIdFromEFT($eft_id);
// echo $eft_id;
// Start transaction for atomicity
$conn->begin_transaction();
try {
// Update the efts table to set status = 'PAID'
$updateEFT = "UPDATE efts SET status = 'PAID' WHERE eft_id = ?";
$stmt = $conn->prepare($updateEFT);
if (!$stmt) {
throw new Exception("Prepare failed: " . $conn->error);
}
$stmt->bind_param("s", $eft_id);
if (!$stmt->execute()) {
throw new Exception("EFT update failed: " . $stmt->error);
}
$stmt->close();
// Retrieve the booking_id from efts table
$getBooking = "SELECT booking_id FROM efts WHERE eft_id = ?";
$stmt = $conn->prepare($getBooking);
if (!$stmt) {
throw new Exception("Prepare failed: " . $conn->error);
}
$stmt->bind_param("s", $eft_id);
$stmt->execute();
$stmt->bind_result($booking_id);
$stmt->fetch();
$stmt->close();
if (!empty($booking_id)) {
// Update the bookings table if booking_id exists
$updateBooking = "UPDATE bookings SET status = 'PAID' WHERE booking_id = ?";
$stmt = $conn->prepare($updateBooking);
if (!$stmt) {
throw new Exception("Prepare failed: " . $conn->error);
}
$stmt->bind_param("i", $booking_id);
if (!$stmt->execute()) {
throw new Exception("Booking update failed: " . $stmt->error);
}
} else {
// If no booking_id is found, update membership_fees instead
$updateMembership = "UPDATE membership_fees SET payment_status = 'PAID' WHERE payment_id = ?";
$stmt = $conn->prepare($updateMembership);
if (!$stmt) {
throw new Exception("Prepare failed: " . $conn->error);
}
$stmt->bind_param("s", $eft_id);
if (!$stmt->execute()) {
throw new Exception("Membership fee update failed: " . $stmt->error);
}
}
$stmt->close();
// Commit transaction if everything was successful
$conn->commit();
sendPaymentConfirmation(getEmail($user), getFullName($user), getEftDescription($eft_id));
header("Location: admin_efts.php");
exit(); // Ensure no further code is executed after the redirect
} catch (Exception $e) {
// Rollback transaction if an error occurs
$conn->rollback();
echo "Error: " . $e->getMessage();
}
// Close database connection
$conn->close();