Files
4WDCSA.co.za/docs/PHASE_1_SECURITY_TESTING_CHECKLIST.md
twotalesanimation be2b757f4e Code restructure push
2025-12-04 15:09:44 +02:00

20 KiB
Raw Permalink Blame History

Phase 1 Security Testing Checklist

4WDCSA.co.za - Pre-Go-Live Validation

Date Created: December 3, 2025
Status: READY FOR TESTING
Phase: 1 - Security & Stability (Weeks 1-3)


1. CSRF (Cross-Site Request Forgery) Protection

Implementation Complete

  • CSRF token generation function: generateCSRFToken() (64-char hex, 1-hour expiry)
  • CSRF token validation: validateCSRFToken() (single-use, auto-removal)
  • All POST forms include hidden CSRF token field
  • All POST processors validate CSRF tokens before processing

Forms Protected (13 forms)

  • login.php - User authentication
  • register.php - New user registration
  • forgot_password.php - Password reset request
  • account_settings.php - Account info form
  • account_settings.php - Password change form
  • trip-details.php - Trip booking
  • campsite_booking.php - Campsite booking
  • course_details.php - Course booking (driver training)
  • bush_mechanics.php - Course booking (bush mechanics)
  • driver_training.php - Course booking
  • comment_box.php - Blog comment submission
  • membership_application.php - Membership application
  • campsites.php (modal) - Add campsite form
  • bar_tabs.php (modal) - Create bar tab form
  • submit_pop.php - Proof of payment upload

Backend Processors Protected (12 processors)

  • validate_login.php - Login validation
  • register_user.php - User registration
  • process_booking.php - Booking processing
  • process_payments.php - Payment processing
  • process_eft.php - EFT processing
  • process_application.php - Application processing
  • process_course_booking.php - Course booking
  • process_camp_booking.php - Campsite booking
  • process_trip_booking.php - Trip booking
  • process_membership_payment.php - Membership payment
  • process_signature.php - Signature processing
  • create_bar_tab.php - Bar tab creation
  • add_campsite.php - Campsite addition
  • submit_order.php - Order submission

Test Cases

Test 1.1: Valid CSRF Token Submission

Steps:

  1. Load login form (captures CSRF token from form)
  2. Fill in credentials
  3. Submit form with valid CSRF token in POST data
  4. Expected result: Login succeeds

Pass Criteria: Login processes successfully

Test 1.2: Missing CSRF Token

Steps:

  1. Create form request with no csrf_token field
  2. POST to login.php
  3. Expected result: 403 error, login fails

Pass Criteria: Response code 403, error message displays

Test 1.3: Invalid CSRF Token

Steps:

  1. Load login form
  2. Modify csrf_token value to random string
  3. Submit form
  4. Expected result: 403 error, login fails

Pass Criteria: Response code 403, error message displays

Test 1.4: Reused CSRF Token

Steps:

  1. Load login form, capture csrf_token
  2. Submit form once (succeeds)
  3. Submit same form again with same token
  4. Expected result: 403 error, second submission fails

Pass Criteria: Second submission rejected

Test 1.5: Cross-Origin CSRF Attempt

Steps:

  1. From external domain (e.g., attacker.com), create hidden form targeting 4WDCSA login
  2. Attempt to submit without CSRF token
  3. Expected result: Failure

Pass Criteria: Request rejected without valid CSRF token


2. AUTHENTICATION & SESSION SECURITY

Implementation Complete

  • Session regeneration after successful login
  • 30-minute session timeout
  • Session cookie security flags (httpOnly, secure, sameSite)
  • Password hashing with password_hash() (argon2id)
  • Email verification for new accounts

Test Cases

Test 2.1: Session Regeneration

Steps:

  1. Get session ID before login
  2. Login successfully
  3. Get session ID after login
  4. Expected result: Session IDs are different

Pass Criteria: Session ID changes after login

Test 2.2: Session Timeout

Steps:

  1. Login successfully
  2. Wait 31 minutes (or manipulate session time)
  3. Attempt to access protected page
  4. Expected result: Redirected to login

Pass Criteria: Session expires after 30 minutes

Test 2.3: Session Fixation Prevention

Steps:

  1. Pre-generate session ID
  2. Create hidden form that sets this session
  3. Attempt to login with pre-set session
  4. Expected result: Session ID should change anyway

Pass Criteria: Session regenerates regardless of initial state

Steps:

  1. Login and inspect response headers
  2. Check Set-Cookie header
  3. Expected result: httpOnly, secure, sameSite=Strict flags present

Pass Criteria: All security flags present

Test 2.5: Plaintext Password Storage

Steps:

  1. Query users table directly
  2. Check password column
  3. Expected result: Hashes, not plaintext (should start with 2y or argon2id)

Pass Criteria: All passwords are hashed


3. RATE LIMITING & ACCOUNT LOCKOUT

Implementation Complete

  • Login attempt tracking in login_attempts table
  • 5 failed attempts = 30-minute lockout
  • IP-based and email-based tracking
  • Audit logging of all lockouts

Test Cases

Test 3.1: Brute Force Prevention

Steps:

  1. Attempt login with wrong password 5 times rapidly
  2. Attempt 6th login
  3. Expected result: Account locked for 30 minutes

Pass Criteria: 6th attempt blocked with lockout message

Test 3.2: Lockout Message

Steps:

  1. After 5 failed attempts, inspect error message
  2. Expected result: Clear message about lockout and duration

Pass Criteria: User-friendly lockout message appears

Test 3.3: Lockout Reset After Timeout

Steps:

  1. Fail login 5 times
  2. Wait 31 minutes (or manipulate database time)
  3. Attempt login with correct credentials
  4. Expected result: Login succeeds

Pass Criteria: Lockout expires automatically

Test 3.4: Successful Login Clears Attempts

Steps:

  1. Fail login 3 times
  2. Login successfully
  3. Fail login again 5 times
  4. Expected result: Lockout happens on 5th attempt (not 2nd)

Pass Criteria: Attempt counter resets after successful login

Test 3.5: IP-Based Rate Limiting

Steps:

  1. From one IP, fail login 5 times
  2. From different IP, attempt login
  3. Expected result: Different IP should not be blocked

Pass Criteria: Rate limiting is per-IP, not global


4. SQL INJECTION PREVENTION

Implementation Complete

  • All queries use prepared statements with parameterized queries
  • getResultFromTable() refactored with column/table whitelisting
  • Input validation on all user-supplied data
  • Audit logging for validation failures

Test Cases

Test 4.1: Login SQL Injection

Steps:

  1. In login form, enter email: ' OR '1'='1
  2. Enter any password
  3. Submit
  4. Expected result: Login fails, no SQL error reveals

Pass Criteria: Login rejected, no database info disclosed

Test 4.2: Booking Date SQL Injection

Steps:

  1. In booking form, modify date parameter to: 2025-01-01'; DROP TABLE bookings;--
  2. Submit form
  3. Expected result: Bookings table still exists, error message appears

Pass Criteria: Table not dropped, invalid input rejected

Test 4.3: Comment SQL Injection

Steps:

  1. In comment box, enter: <script>alert('xss')</script>' OR '1'='1
  2. Submit comment
  3. Expected result: Stored safely as text, no execution

Pass Criteria: Comment stored but not executed

Test 4.4: Union-Based SQL Injection

Steps:

  1. In search field, enter: '; UNION SELECT user_id, password FROM users;--
  2. Expected result: Query fails, no results

Pass Criteria: Union injection blocked

Test 4.5: Prepared Statement Verification

Steps:

  1. Review process_booking.php code
  2. Verify all database queries use $stmt->bind_param()
  3. Expected result: No direct variable interpolation in SQL

Pass Criteria: All queries use prepared statements


5. XSS (Cross-Site Scripting) PREVENTION

Implementation Complete

  • Output encoding with htmlspecialchars()
  • Input validation on all form fields
  • Content Security Policy headers (recommended)

Test Cases

Test 5.1: Stored XSS in Comments

Steps:

  1. In comment form, enter: <script>alert('XSS')</script>
  2. Submit comment
  3. View blog post
  4. Expected result: Script does NOT execute, appears as text

Pass Criteria: Script tag appears as text, no alert()

Test 5.2: Reflected XSS in Search

Steps:

  1. Navigate to search page with: ?search=<img src=x onerror=alert('xss')>
  2. Expected result: No alert, image tag fails, text displays

Pass Criteria: No JavaScript execution

Test 5.3: DOM-Based XSS in Member Details

Steps:

  1. In member info form, enter name: "><script>alert('xss')</script>
  2. Save
  3. View member profile
  4. Expected result: Name displays with quotes escaped

Pass Criteria: HTML injection prevented

Test 5.4: Event Handler XSS

Steps:

  1. In profile update, attempt: onload=alert('xss')
  2. Submit
  3. Expected result: onload attribute removed or escaped

Pass Criteria: Event handlers sanitized

Test 5.5: Data Attribute XSS

Steps:

  1. In form, enter: <div data-code="javascript:alert('xss')"></div>
  2. Submit
  3. Expected result: Safe storage, no execution

Pass Criteria: Data attributes safely stored


6. FILE UPLOAD VALIDATION

Implementation Complete

  • Hardcoded MIME type whitelist per file type
  • File size limits enforced (5MB images, 10MB documents)
  • Extension validation
  • Double extension prevention
  • Random filename generation
  • is_uploaded_file() verification
  • Image validation with getimagesize()

Test Cases

Test 6.1: Malicious File Extension

Steps:

  1. Attempt to upload shell.php.jpg (PHP shell with JPG extension)
  2. Expected result: Upload rejected

Pass Criteria: Double extension detected and blocked

Test 6.2: Executable File Upload

Steps:

  1. Attempt to upload shell.exe or shell.sh
  2. Expected result: Upload rejected, error message

Pass Criteria: Executable file types blocked

Test 6.3: File Size Limit

Steps:

  1. Create 6MB image file
  2. Attempt upload as profile picture (5MB limit)
  3. Expected result: Upload rejected

Pass Criteria: Size limit enforced

Test 6.4: MIME Type Mismatch

Steps:

  1. Rename shell.php to shell.jpg
  2. Attempt upload
  3. Expected result: Upload rejected (MIME type is PHP)

Pass Criteria: MIME type validation catches mismatch

Test 6.5: Random Filename Generation

Steps:

  1. Upload two profile pictures
  2. Check uploads directory
  3. Expected result: Both have random names, not original

Pass Criteria: Filenames are randomized

Test 6.6: Image Validation

Steps:

  1. Create text file with .jpg extension
  2. Attempt to upload as profile picture
  3. Expected result: getimagesize() fails, upload rejected

Pass Criteria: Invalid images rejected

Test 6.7: File Permissions

Steps:

  1. Upload a file successfully
  2. Check file permissions
  3. Expected result: 0644 (readable but not executable)

Pass Criteria: Files not executable after upload

Test 6.8: Path Traversal Prevention

Steps:

  1. Attempt upload with filename: ../../../shell.php
  2. Expected result: Random name assigned, path traversal prevented

Pass Criteria: Upload location cannot be changed


7. INPUT VALIDATION

Implementation Complete

  • Email validation (format + length)
  • Phone number validation
  • Name validation (no special characters)
  • Date validation (proper format)
  • Amount validation (numeric, reasonable ranges)
  • ID number validation (South African format)
  • Password strength validation (min 8 chars, special char, number, uppercase)

Test Cases

Test 7.1: Invalid Email Format

Steps:

  1. In registration, enter email: notanemail
  2. Submit form
  3. Expected result: Form rejected with error

Pass Criteria: Invalid emails rejected

Test 7.2: Email Too Long

Steps:

  1. In registration, enter email with 300+ characters
  2. Submit form
  3. Expected result: Form rejected with error

Pass Criteria: Email length limit enforced

Test 7.3: Phone Number Validation

Steps:

  1. In application form, enter phone: abc123
  2. Submit
  3. Expected result: Form rejected

Pass Criteria: Non-numeric phones rejected

Test 7.4: Name with SQL Characters

Steps:

  1. In application, enter name: O'Brien'; DROP TABLE--
  2. Submit
  3. Expected result: Name safely stored without SQL execution

Pass Criteria: Special characters handled safely

Test 7.5: Invalid Date Format

Steps:

  1. In booking form, enter date: 32/13/2025
  2. Submit
  3. Expected result: Form rejected with error

Pass Criteria: Invalid dates rejected

Test 7.6: Weak Password

Steps:

  1. In registration, enter password: password123
  2. Submit
  3. Expected result: Form rejected (needs uppercase, special char)

Pass Criteria: Weak passwords rejected

Test 7.7: Password Strength Check

Steps:

  1. Enter password: SecureP@ssw0rd
  2. Expected result: Password accepted

Pass Criteria: Strong passwords accepted

Test 7.8: Negative Amount Submission

Steps:

  1. In booking, attempt to set amount to -100
  2. Submit
  3. Expected result: Invalid amount rejected

Pass Criteria: Negative amounts blocked


8. AUDIT LOGGING & MONITORING

Implementation Complete

  • auditLog() function logs all security events
  • audit_log table stores: user_id, action, table, record_id, details, timestamp
  • Failed login attempts logged
  • CSRF failures logged
  • Failed validations logged
  • File upload operations logged
  • Admin actions logged

Test Cases

Test 8.1: Login Attempt Logged

Steps:

  1. Perform successful login
  2. Query audit_log table
  3. Expected result: LOGIN_SUCCESS entry present

Pass Criteria: Login logged with timestamp

Test 8.2: Failed Login Attempt Logged

Steps:

  1. Attempt login with wrong password
  2. Query audit_log table
  3. Expected result: LOGIN_FAILED entry present

Pass Criteria: Failed login logged

Test 8.3: CSRF Failure Logged

Steps:

  1. Submit form with invalid CSRF token
  2. Query audit_log table
  3. Expected result: CSRF_VALIDATION_FAILED entry

Pass Criteria: CSRF failures tracked

Test 8.4: File Upload Logged

Steps:

  1. Upload profile picture
  2. Query audit_log table
  3. Expected result: PROFILE_PIC_UPLOAD entry with filename

Pass Criteria: Uploads tracked with details

Test 8.5: Audit Log Queryable

Steps:

  1. Admin queries audit log for specific user
  2. View all actions performed by user
  3. Expected result: Complete action history visible

Pass Criteria: Audit trail is complete and accessible


9. DATABASE SECURITY

Implementation Complete

  • Database user with limited privileges (no DROP, no ALTER)
  • Prepared statements throughout
  • login_attempts table for rate limiting
  • audit_log table for security events
  • users.locked_until column for account lockout

Test Cases

Test 9.1: Database User Permissions

Steps:

  1. Connect as database user (not admin)
  2. Attempt to DROP table
  3. Expected result: Permission denied

Pass Criteria: Database user cannot drop tables

Test 9.2: Backup Encryption

Steps:

  1. Check database backup location
  2. Verify backups are encrypted
  3. Expected result: Backups not readable without key

Pass Criteria: Backups secured

Test 9.3: Connection Encryption

Steps:

  1. Check database connection settings
  2. Verify SSL/TLS enabled
  3. Expected result: Database uses encrypted connection

Pass Criteria: Database traffic encrypted


10. DEPLOYMENT & CONFIGURATION SECURITY

Implementation Needed Before Go-Live

  • Remove phpinfo() calls
  • Hide error messages from users (log to file instead)
  • Set error_reporting to E_ALL but display_errors = Off
  • Remove debug code and print_r() statements
  • Update .htaccess to disable directory listing
  • Set proper file permissions (644 for PHP, 755 for directories)
  • Verify HTTPS enforced on all pages
  • Update robots.txt to allow search engines
  • Review sensitive file access (no direct access to uploads)
  • Set Content-Security-Policy headers

Pre-Go-Live Checklist

  • phpinfo.php deleted
  • testenv.php deleted
  • env.php contains production credentials
  • Database backups configured and tested
  • Backup restoration procedure documented
  • Incident response plan documented
  • Admin contact information documented

11. PERFORMANCE & STABILITY

Implementation Complete

  • Database queries optimized with indexes
  • Session cleanup for expired CSRF tokens
  • Error handling prevents partial failures

Test Cases

Test 11.1: Large Comment Load

Steps:

  1. Load blog post with 1000+ comments
  2. Measure page load time
  3. Expected result: Loads within 3 seconds

Pass Criteria: Performance acceptable

Test 11.2: Concurrent User Stress

Steps:

  1. Simulate 50 concurrent users logging in
  2. Monitor database connections
  3. Expected result: No timeouts, all succeed

Pass Criteria: System handles load

Test 11.3: Session Cleanup

Steps:

  1. Generate 1000 CSRF tokens
  2. Wait for expiration (1 hour)
  3. Check session size
  4. Expected result: Session not bloated, tokens cleaned

Pass Criteria: Cleanup occurs properly


12. GO-LIVE SECURITY SIGN-OFF

Requirements Before Production Deployment

Security Review

  • All 11 Phase 1 tasks completed and tested
  • No known security vulnerabilities
  • Audit log functional and accessible
  • Backup and recovery tested
  • Incident response plan documented

Code Review

  • No debug code in production files
  • No direct SQL queries (all parameterized)
  • No hardcoded credentials
  • All error messages user-friendly
  • HTTPS enforced on all pages

Deployment Review

  • Database migrated successfully
  • All tables created with proper indexes
  • File permissions set correctly (644/755)
  • Upload directories outside web root (if possible)
  • Backups configured and tested
  • Monitoring/logging configured

User Communication

  • Security policy documented and communicated
  • Password requirements communicated
  • MFA/email verification process clear
  • Incident contact information provided
  • Data privacy policy updated

13. SIGN-OFF

Tested By

  • QA Team: _________________________ Date: _________
  • Security Team: _________________________ Date: _________
  • Project Manager: _________________________ Date: _________

Approved For Deployment

  • Authorized By: _________________________ Date: _________
  • Title: _________________________________

Notes & Issues

[Space for any issues found and resolutions]

Next Steps After Phase 1 (Phase 2 - Hardening)

  1. Implement Web Application Firewall (WAF)

    • Add ModSecurity or equivalent
    • Block known attack patterns
  2. Add Rate Limiting at HTTP Level

    • Prevent DDoS attacks
    • Limit API requests per IP
  3. Implement Content Security Policy (CSP)

    • Restrict script sources
    • Prevent inline script execution
  4. Add Database Connection Pooling

    • Replace global $conn with connection pool
    • Improve performance under load
  5. Implement API Authentication

    • Add JWT or OAuth for API calls
    • Secure AJAX requests
  6. Add Security Headers

    • X-Frame-Options: DENY
    • X-Content-Type-Options: nosniff
    • Strict-Transport-Security: max-age=31536000
  7. Automated Security Testing

    • Add OWASP ZAP to CI/CD pipeline
    • Automated SQL injection testing
    • Automated XSS testing

End of Security Testing Checklist