Files
4WDCSA.co.za/TASK_9_ADD_CSRF_FORMS.md
twotalesanimation ce6c8e257a Add Phase 1 progress documentation and Task 9 quick-start guide
- PHASE_1_PROGRESS.md: Comprehensive progress report (66% complete)
  - Documents all 7 completed security tasks
  - Lists remaining 4 tasks with estimates
  - Security improvements summary
  - Database changes required
  - Files modified and testing verification

- TASK_9_ADD_CSRF_FORMS.md: Quick-start guide for adding CSRF tokens
  - Step-by-step instructions for form modification
  - List of ~40 forms that need tokens (prioritized)
  - Common patterns and examples
  - Validation reference
  - Troubleshooting guide
  - Testing checklist

Ready for Task 9 implementation (form template updates)
2025-12-03 11:31:09 +02:00

6.6 KiB

Phase 1 Task 9: Add CSRF Tokens to Forms - Quick Start Guide

What to Do

Every <form method="POST"> in the application needs a CSRF token hidden field.

How to Add CSRF Token to a Form

Simple One-Line Addition

Add this ONE line before the closing </form> tag:

<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">

Complete Form Example

Before (Vulnerable):

<form method="POST" action="process_booking.php">
    <input type="text" name="from_date" required>
    <input type="text" name="to_date" required>
    <button type="submit">Book Now</button>
</form>

After (Secure):

<form method="POST" action="process_booking.php">
    <input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
    <input type="text" name="from_date" required>
    <input type="text" name="to_date" required>
    <button type="submit">Book Now</button>
</form>

Forms to Update (Estimated 40+)

Priority 1: Authentication & Membership (5 forms)

  • login.php - Login form
  • register.php - Registration form
  • forgot_password.php - Password reset request
  • reset_password.php - Password reset form
  • change_password.php - Change password form

Priority 2: Bookings (6 forms)

  • campsite_booking.php - Campsite booking form
  • trips.php - Trip booking form
  • course_details.php - Course booking form
  • membership_application.php - Membership application form
  • update_application.php - Update membership form
  • view_indemnity.php - Indemnity acceptance form

Priority 3: Account Management (4 forms)

  • account_settings.php - Account settings form
  • update_user.php - User profile update form
  • member_info.php - Member info edit form
  • upload_profile_picture.php - Profile picture upload form

Priority 4: Admin Pages (6+ forms)

  • admin_members.php - Admin member management forms
  • admin_bookings.php - Admin booking management
  • admin_payments.php - Admin payment forms
  • admin_course_bookings.php - Course management
  • admin_trip_bookings.php - Trip management
  • admin_camp_bookings.php - Campsite management

Priority 5: Other Forms (10+ forms)

  • comment_box.php
  • contact.php
  • blog_details.php (if has comment form)
  • bar_tabs.php / fetch_bar_tabs.php
  • events.php
  • create_bar_tab.php
  • Any other POST forms

Search Strategy

Option 1: Use Grep to Find All Forms

# Find all forms in the application
grep -r "method=\"POST\"" --include="*.php" .

# Or find AJAX forms that might not have method="POST"
grep -r "<form" --include="*.php" . | grep -v method

Option 2: Manual File-by-File Check

Look for these patterns:

  • <form method="POST"
  • <form (default is POST if not specified)
  • <form method='POST'

Common Patterns

Standard Form

<form method="POST">
    <!-- fields -->
    <input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
    <button type="submit">Submit</button>
</form>

Form with Action

<form method="POST" action="process_booking.php">
    <!-- fields -->
    <input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
    <button type="submit">Submit</button>
</form>

AJAX Form (Special Case)

For AJAX/JavaScript forms that serialize and POST:

// In your JavaScript, before sending:
const formData = new FormData(form);
formData.append('csrf_token', '<?php echo generateCSRFToken(); ?>');

Admin/Modal Forms

<form method="POST" class="modal-form">
    <input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
    <!-- fields -->
</form>

Validation Reference

After adding CSRF tokens, the server-side code already validates them:

Login Endpoint

validate_login.php - CSRF validation implemented

Registration Endpoint

register_user.php - CSRF validation implemented

Booking Endpoints

process_booking.php - CSRF validation implemented process_camp_booking.php - CSRF validation implemented process_trip_booking.php - CSRF validation implemented process_course_booking.php - CSRF validation implemented process_signature.php - CSRF validation implemented process_application.php - CSRF validation implemented process_eft.php - CSRF validation implemented

If you add CSRF to a form but the endpoint doesn't validate it yet, the form will still work but the endpoint needs to be updated to include:

if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
    // Handle CSRF error
    echo json_encode(['status' => 'error', 'message' => 'Security token validation failed.']);
    exit();
}

Testing After Adding Tokens

  1. Normal submission: Form should work as before
  2. Missing token: Form should be rejected (if endpoint validates)
  3. Invalid token: Form should be rejected (if endpoint validates)
  4. Expired token (after 1 hour): New token needed

Performance Note

generateCSRFToken() is called once per page load. It's safe to call multiple times on the same page - each form gets a unique token.

Common Issues & Solutions

Issue: "Token validation failed" error

Solution: Ensure csrf_token is passed in the POST data. Check:

  1. Form includes <input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
  2. Form method is POST (not GET)
  3. JavaScript doesn't strip the field

Issue: Forms in modals not working

Solution: Ensure token is inside the modal's form tag, not outside

Issue: Multi-page forms not working

Solution: Each page needs its own token. Token changes with each page load. This is intentional (single-use tokens).

Checklist for Task 9

  • Identify all forms with method="POST" or no method specified
  • Add <input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>"> to each
  • Test 5 critical forms to verify they still work
  • Test that form submission without CSRF token fails (if endpoint validates)
  • Verify password reset, login, and booking flows work
  • Commit changes with message: "Add CSRF tokens to all form templates"

Files to Reference

  • functions.php - See generateCSRFToken() function (~line 2000)
  • validate_login.php - Example of CSRF validation in action
  • register_user.php - Example of CSRF validation in action
  • PHASE_1_PROGRESS.md - Current progress documentation

Estimated Time: 2-3 hours
Difficulty: Low (repetitive task, minimal logic changes)
Impact: High (protects against CSRF attacks)
Status: READY TO START